I am receiving this error when I attempt to use geolocation:
Map: Geometry (wkid: 4326) cannot be converted to spatial reference of the map (wkid: 3435)
What do I need to add in my following code to make this work?
<!DOCTYPE html>
<html>
<head>
<title>Create a Map</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="http://js.arcgis.com/3.11/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.11/esri/css/esri.css">
<style>
html, body, #mapDiv
{
padding:0;
margin:0;
height:100%;
width:100%;
}
@-webkit-keyframes
pulse
{
0%
{
opacity:1.0;
}
45%
{
opacity:.20;
}
{
100%
{
opacity:1.0;
}
}
@-moz-keyframes
pulse
{
0%
{
opacity:1.0;
}
45%
{
opacity:.20;
}
100%
{
opacity:1.0;
}
}
#map_graphics_layer {
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-name: pulse;
-moz-animation-duration: 3s;
-moz-animation-iteration-count: infinite;
-moz-animation-name: pulse;
}
</style>
<script src="http://js.arcgis.com/3.11/"></script>
<script>
var map;
var graphic;
var currLocation;
var watchId;
require(["esri/map", "esri/config",
"esri/Color",
"esri/geometry/Extent",
"esri/geometry/Point",
"esri/graphic",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/layers/ArcGISTiledMapServiceLayer",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleMarkerSymbol",
"esri/tasks/GeometryService",
"dojo/dom",
"dojo/on",
"dojo/parser",
"dojo/domReady!"], function (Map, esriConfig, Color, Extent, Point, Graphic,
ArcGISDynamicMapServiceLayer, ArcGISTiledMapServiceLayer,
SimpleLineSymbol, SimpleMarkerSymbol, GeometryService, dom, on, parser
) {
// set custom extent
var initialExtent = new Extent({
"xmin": 777229.03,
"ymin": 1133467.92,
"xmax": 848340.14,
"ymax": 1185634.58,
"spatialReference": {
"wkid": 3435
}
});
// create map and set slider style to small
map = new Map("mapDiv", {
showAttribution: false,
sliderStyle: "small",
extent: initialExtent
});
// add imagery
var tiled = new ArcGISTiledMapServiceLayer("http://maps.decaturil.gov/arcgis/rest/services/Aerial_2014_Tiled/MapServer");
map.addLayer(tiled);
// set operational layers
var operationalLayer = new ArcGISDynamicMapServiceLayer("http://maps.decaturil.gov/arcgis/rest/services/Public/InternetVector/MapServer", { "opacity": 0.5 });
// add operational layers
map.addLayer(operationalLayer);
// declare geometry service
esriConfig.defaults.geometryService = new GeometryService("http://maps.decaturil.gov/arcgis/rest/services/Utilities/Geometry/GeometryServer");
// geolocation functionality starts here
map.on("load", initFunc);
function orientationChanged() {
if (map) {
map.reposition();
map.resize();
}
}
function initFunc(map) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(zoomToLocation, locationError);
watchId = navigator.geolocation.watchPosition(showLocation, locationError);
} else {
alert("Browser doesn't support Geolocation. Visit http://caniuse.com to see browser support for the Geolocation API.");
}
}
function locationError(error) {
//error occurred so stop watchPosition
if (navigator.geolocation) {
navigator.geolocation.clearWatch(watchId);
}
switch (error.code) {
case error.PERMISSION_DENIED:
alert("Location not provided");
break;
case error.POSITION_UNAVAILABLE:
alert("Current location not available");
break;
case error.TIMEOUT:
alert("Timeout");
break;
default:
alert("unknown error");
break;
}
}
function zoomToLocation(location) {
var pt = new Point(location.coords.longitude, location.coords.latitude);
addGraphic(pt);
map.centerAndZoom(pt, 12);
}
function showLocation(location) {
//zoom to the users location and add a graphic
var pt = new Point(location.coords.longitude, location.coords.latitude);
if (!graphic) {
addGraphic(pt);
} else { // move the graphic if it already exists
graphic.setGeometry(pt);
}
map.centerAt(pt);
}
function addGraphic(pt) {
var symbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
12,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color([210, 105, 30, 0.5]),
8
),
new Color([210, 105, 30, 0.9])
);
graphic = new Graphic(pt, symbol);
map.graphics.add(graphic);
}
}
);
</script>
</head>
<body onorientationchange="orientationChanged();" class="soria">
<div id="mapDiv"></div>
</body>
</html>
Solved! Go to Solution.
Chris,
Your issue is the the project method is an async method and you have to wait for its response before the pnt is actually projected. Your next issue is that the outSR is not expecting a string, but an actual SpatialReference object. The final issue is you are assigning a transformation (as you should be) but you are using the wkid of 4326, which is not a transformation wkid.
Here is your code updated:
<!DOCTYPE html>
<html>
<head>
<title>Create a Map</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="http://js.arcgis.com/3.11/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.11/esri/css/esri.css">
<style>
html,
body,
#mapDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
@-webkit-keyframes
pulse {
0% {
opacity: 1.0;
}
45% {
opacity: .20;
}
{
100% {
opacity: 1.0;
}
}
@-moz-keyframes
pulse {
0% {
opacity: 1.0;
}
45% {
opacity: .20;
}
100% {
opacity: 1.0;
}
}
#map_graphics_layer {
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-name: pulse;
-moz-animation-duration: 3s;
-moz-animation-iteration-count: infinite;
-moz-animation-name: pulse;
}
</style>
<script src="http://js.arcgis.com/3.11/"></script>
<script>
var map;
var graphic;
var currLocation;
var watchId;
var pt;
require(["esri/map", "esri/config",
"esri/Color",
"esri/geometry/Extent",
"esri/geometry/Point",
"esri/graphic",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/layers/ArcGISTiledMapServiceLayer",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleMarkerSymbol",
"esri/tasks/GeometryService",
"esri/tasks/ProjectParameters",
"esri/SpatialReference",
"dojo/dom",
"dojo/on",
"dojo/parser",
"dojo/domReady!"], function (Map, esriConfig, Color, Extent, Point, Graphic,
ArcGISDynamicMapServiceLayer, ArcGISTiledMapServiceLayer,
SimpleLineSymbol, SimpleMarkerSymbol, GeometryService, ProjectParameters, SpatialReference, dom, on, parser
) {
// set custom extent
var initialExtent = new Extent({
"xmin": 777229.03,
"ymin": 1133467.92,
"xmax": 848340.14,
"ymax": 1185634.58,
"spatialReference": {
"wkid": 3435
}
});
// create map and set slider style to small
map = new Map("mapDiv", {
showAttribution: false,
sliderStyle: "small",
extent: initialExtent
});
// add imagery
var tiled = new ArcGISTiledMapServiceLayer("http://maps.decaturil.gov/arcgis/rest/services/Aerial_2014_Tiled/MapServer");
map.addLayer(tiled);
// set operational layers
var operationalLayer = new ArcGISDynamicMapServiceLayer("http://maps.decaturil.gov/arcgis/rest/services/Public/InternetVector/MapServer", {
"opacity": 0.5
});
// add operational layers
map.addLayer(operationalLayer);
// declare geometry service
esriConfig.defaults.geometryService = new GeometryService("http://maps.decaturil.gov/arcgis/rest/services/Utilities/Geometry/GeometryServer");
// geolocation functionality starts here
map.on("load", initFunc);
function orientationChanged() {
if (map) {
map.reposition();
map.resize();
}
}
function initFunc(map) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(zoomToLocation, locationError);
watchId = navigator.geolocation.watchPosition(showLocation, locationError);
} else {
alert("Browser doesn't support Geolocation. Visit http://caniuse.com to see browser support for the Geolocation API.");
}
}
function locationError(error) {
//error occurred so stop watchPosition
if (navigator.geolocation) {
navigator.geolocation.clearWatch(watchId);
}
switch (error.code) {
case error.PERMISSION_DENIED:
alert("Location not provided");
break;
case error.POSITION_UNAVAILABLE:
alert("Current location not available");
break;
case error.TIMEOUT:
alert("Timeout");
break;
default:
alert("unknown error");
break;
}
}
function zoomToLocation(location) {
var geopt = new Point(location.coords.longitude, location.coords.latitude);
var params = new ProjectParameters();
params.geometries = [geopt];
params.outSR = new SpatialReference(3435);
params.transformation = 108190;
params.transformForward = true;
esriConfig.defaults.geometryService.project(params, function(projectedPoints){
pt = projectedPoints[0];
addGraphic(pt);
map.centerAndZoom(pt, 12);
});
}
function showLocation(location) {
//zoom to the users location and add a graphic
var geopt = new Point(location.coords.longitude, location.coords.latitude);
var params = new ProjectParameters();
params.geometries = [geopt];
params.outSR = new SpatialReference(3435);
params.transformation = 108190;
params.transformForward = true;
esriConfig.defaults.geometryService.project(params, function(projectedPoints){
pt = projectedPoints[0];
if (!graphic) {
addGraphic(pt);
} else { // move the graphic if it already exists
graphic.setGeometry(pt);
}
map.centerAt(pt);
});
}
function addGraphic(pt) {
var symbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
12,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color([210, 105, 30, 0.5]),
8
),
new Color([210, 105, 30, 0.9])
);
graphic = new Graphic(pt, symbol);
map.graphics.add(graphic);
}
});
</script>
</head>
<body onorientationchange="orientationChanged();" class="soria">
<div id="mapDiv"></div>
</body>
</html>
Maybe create a Spatial reference
var sr = new SpatialReference(4326);
and then when you create the map add it
map = new Map("mapDiv", {
showAttribution: false,
sliderStyle: "small",
extent: initialExtent,
spatialReference: sr
});
then the location will be the same as the SR of the map - because the map is now 4326
It looks like this would conflict with my extent:initialExtent which uses a different spatial reference. I tried it though and I receive a blank page.
Yes, your initial extent will now need to be in latlong (4326 )
Our data uses a wkid of 3435. For accuracy, we need to use the 3435 wkid. The init.js file has a wkid of 4326, but I'm not sure how to work with the two to convert what I need.
That is werd because the docs say that if you construct the map with an Extend and spatial reference,everything should work as long as all other layers match.
map-amd | API Reference | ArcGIS API for JavaScript
If provided, the extent and projection of the map is set to the properties of Extent. Once the projection is set, all layers must be able to be drawn in the defined projection. The tiling scheme of an ArcGISTiledMapServiceLayer must match the projection of the map. The projection of the extent is honored when used in the map constructor.
What you may want to try Chris is don't initialize the extent in the constructor, instead wait for the map to load the tiled layer and then set the extent. It will inherit the spatial reference and default extents of the tiled layer and should accept the new extent.
I had a similar issue in a local NAD spatial reference and in my case I think I just dropped the initial extent altogether, I could never get it to honor it and now I just have the map move to the previously loaded extent after it has been created.
How should I modify the code to do that?
You could try something like this.
// set custom extent var initialExtent = new Extent({ "xmin": 777229.03, "ymin": 1133467.92, "xmax": 848340.14, "ymax": 1185634.58, "spatialReference": { "wkid": 3435 } }); // create map and set slider style to small **LEAVE OUT EXTENT HERE** map = new Map("mapDiv", { showAttribution: false, sliderStyle: "small" }); // geolocation functionality starts here map.on("load", initFunc); // **SET LOAD LISTENER BEFORE ADDING TILED LAYER** // add imagery var tiled = new ArcGISTiledMapServiceLayer("http://maps.decaturil.gov/arcgis/rest/services/Aerial_2014_Tiled/MapServer"); map.addLayer(tiled); function initFunc(map) { map.setExtent(initialExtent); // **SET EXTENT HERE** if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(zoomToLocation, locationError); watchId = navigator.geolocation.watchPosition(showLocation, locationError); } else { alert("Browser doesn't support Geolocation. Visit http://caniuse.com to see browser support for the Geolocation API."); } }
You need to project the graphic into your maps spatial reference. That should fix everything. geometryservice-amd | API Reference | ArcGIS API for JavaScript
You could just use the LocateButton to handle all of this code for you.
locatebutton-amd | API Reference | ArcGIS API for JavaScript
I was thinking something like this:
require(["esri/geometry/Point"], function(Point) { new Point(x,y,3435});
but since it's geolocation I don't know what the x and y will be. And is this code even correct that I wrote?