Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
807 views
in Technique[技术] by (71.8m points)

arcgis js api - How to set the spatial reference of a ESRI Javascript API map (3.x)?

Is it possible to change the spatial references of a map without providing a basemap? I would like to use a custom spatial reference so I can use custom lods.

In the sample below, if I uncomment the "streets" basemap the 6 features are rendered on the map.

But with it commented out I only see the vertical features because the map remains in 4326 and the 3857 points are not visible.

Assigning a value to the map.spatialReference has no effect.

Is it possible to impose a default spatial reference on the map without using a basemap? In the code below I tried using center, extent and direct assignment to the spatialReference but the only thing that worked was using the "streets" basemap, which I do not want to use.

import Map from "esri/map";
import SpatialReference from "esri/SpatialReference";
import Scalebar from "esri/dijit/Scalebar";
import GraphicsLayer from "esri/layers/GraphicsLayer";
import Graphic from "esri/graphic";
import Point from "esri/geometry/Point";
import Extent from "esri/geometry/Extent";
import SimpleMarkerSymbol from "esri/symbols/SimpleMarkerSymbol";
import SimpleLineSymbol from "esri/symbols/SimpleLineSymbol";
import Color from "esri/Color";
import * as projection from "esri/geometry/projection";

import "dojo/domReady!";

const range = (n: number) => {
  return new Array(n).fill(n).map((_, i) => i);
};

const createMarker = (color: number) =>
  new SimpleMarkerSymbol(
    "solid",
    8,
    new SimpleLineSymbol(),
    new Color([color, color, color, 1])
  );

const baselineResolution = 156543.03408771486;
const baselineScale = 591657527.591555;

const lods = range(30).map((i) => {
  const level = i;
  const resolution = baselineResolution / Math.pow(2, level);
  const scale = baselineScale / Math.pow(2, level);
  return { level, resolution, scale, levelValue: "level" };
});

export async function run() {
  await projection.load();

  const srs3857 = new SpatialReference({ wkid: 3857 });
  const srs4326 = new SpatialReference({ wkid: 4326 });

  console.log({ lods });

  const center = new Point(-9462156, 4300621, srs3857);
  const extent = new Extent(
    center.x - 1000,
    center.y - 1000,
    center.x + 1000,
    center.y + 1000,
    srs3857
  );

  // zoom levels are broken without specifying a basemap
  const map = new Map("map", {
    //basemap: "streets",
    center, // does not set the map srs
    extent, // does not set the map srs
    lods: lods,
    zoom: 14,
  });

  console.log(map.spatialReference); // undefined
  map.spatialReference = srs3857; // has no affect?

  new Scalebar({ map: map, scalebarUnit: "dual" });

  const graphicsLayer = new GraphicsLayer();
  map.addLayer(graphicsLayer);

  // these do not render
  [-85, -85.01, -84.99]
    .map(
      (x) => projection.project(new Point(x, 36.0, srs4326), srs3857) as Point
    )
    .forEach((p, i) =>
      graphicsLayer.add(new Graphic(p, createMarker(i * 10), {}))
    );

  // these do render
  [36, 36.01, 35.99]
    .map(
      (y) => projection.project(new Point(-85, y, srs4326), srs4326) as Point
    )
    .forEach((p, i) =>
      graphicsLayer.add(new Graphic(p, createMarker(i * 10), {}))
    );
}

I did find this one trick that sets the map up correctly but I would prefer a real solution:

  // trick to get the map to work properly
  map.on("load", () =>
    setTimeout(() => map.removeLayer(map.getLayer(map.basemapLayerIds[0])), 0)
  );
question from:https://stackoverflow.com/questions/65904709/how-to-set-the-spatial-reference-of-a-esri-javascript-api-map-3-x

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...