cmv / cmv-app

CMV - The Configurable Map Viewer - A community supported open source mapping framework built with the Esri JavaScript API and the Dojo Toolkit
https://demo.cmv.io/
MIT License
325 stars 278 forks source link

Non Mercator Coordinates in Measure Widget #227

Closed carey136 closed 10 years ago

carey136 commented 10 years ago

Is it possible to configure the default measure widget to deliver coordinates in x,y format rather that Lat,Long?

My problem stems from the fact all the data we publish is in OSGB36 (British National Grid, wkid:27700). The MapInfo widget does a brilliant job of displaying the coordinates of the mouse pointer in the correct coordinate system, but many of our users will be looking to identify a points using the measure tool and copy the results into other applications/documents.

The use of a local map projection means that the other functions of the measure tool also return an incorrect result. Having checked through previous issues, I came across issue #83, concerning the additional Coordinate Transformation Widget. I had no luck configuring this to work with 27700 either.

Any ideas? Thanks!

tmcgee commented 10 years ago

You'll need to setup a Geometry Service if you haven't already. The CMV measurement widget uses the standard ESRI Measurement widget. Note the first paragraph on that page regarding using Geometry Service for maps that are not web mercator/geographic.

Regarding the Coordinate Transformation widget, there is a caveat in the readme that it had not been tested with non web mercator basemaps. You may be the first to try it that way. Your projection is supported by the proj4js library that we use for this on-the-fly re-projection. http://spatialreference.org/ref/epsg/27700/

Out of curiosity, does the StreetView widget work for you? It uses the same proj4js library to re-project the coordinates on the fly to get the location for StreetView.

carey136 commented 10 years ago

The streetview widget works perfectly, even with the background mapping and layers being in 27700.

The Geometry Service from ArcGIS Server has been specified in viewer.js as per the documentation, does this need to be specified in any other location?

tmcgee commented 10 years ago

It looks to me that the ESRI Measurement widget doe not support this for the "Get Location" tool though it does for the length and area tools.

I think your best bet would be to work with @tr3v0rm to consider support for non web mercator basemaps in his projections widget.

tr3vorm commented 10 years ago

I will look at this today. I have yet to install the new release of CMV (1.3) and I believe there is some work to get the widget working with the new release @tmcgee with regard to mapClickMode? I have only used this widget with AGOL basemaps, and dynamic layers using NZTM (SRID:2193). I just tried 27700 on my config and it works fine but I will try use a non-web mercator basemap later.

tmcgee commented 10 years ago

@tr3vorm check out issue #219 where I provided some guidance about necessary changes to update widgets with MapClickMode for cmv v1.3.0.

carey136 commented 10 years ago

An interesting observation here. I am currently using a local copy of the 3.10 compact JSAPI and decided to check the measure tool in the core javascript.

I replaced all instances of WKID:4326 to WKID:27700 within the file \library\3.10\3.10compact\js\esri\dijit\measurement.js. The effect of this was to deliver the coordinates in the correct eastings and northings expected of the projection. To verify this, the MapInfo widget gave the exact same coordinate as seen by the esri measure widget.

This also led to the measure tool correctly measuring the areas and lengths as well.

Of course, editing the measure tool in the API directly isn't a solution i'd like to entertain (that and the fact that the headings for the coordinates in the measure results are still "latitude" and "longitude"). This does prove however that the tool can and will support the projected coordinate system we require, just with more tweaking the the API than prefered.

The attached image displays the coordinates as viewed with the modified WKID. image

carey136 commented 10 years ago

Found some useful info from this thread over on ESRI GeoNet concerning the measure tool.

https://geonet.esri.com/thread/104339

The inclusion of the line-

advancedLocationUnits: true,

which follows the line-

this.measure = new Measurement({

in the measurement.js digit from CMV viewer adds a number of extra unit types for location. (Degrees, DMS, MGRS, USNG, UTM, GeoRef and GARS).

Unfortunately there is no result in the measurement table when using any other unit that degrees or DMS (it appears as 'undefined') using the default 1.3 version of the CMV viewer with ESRI geometry service, or with our local data and geometry service.

However, the fact that the result comes back as undefined (in the HTML output when viewing the app measure result through a browser), means that it should be possible to define it somewhere?

carey136 commented 10 years ago

Further to the previous post, the use of a ESRI 10.21 geometry service (tested using the sample server found at http://sampleserver5.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer), returns:

"Geometry Service Error"

in the measurement results table when using any of the new projections.

This hasn't been tested with a 10.2.2 geometry service yet.

tr3vorm commented 10 years ago

@carey136 I am looking at this now - just so I am clear, you are not using any AGOL base maps, and using your own basemap in 27700. PS. That pic is familiar - I worked in Middlesbrough late 90's on a project.

carey136 commented 10 years ago

To clarify, we using our own basemaps in 27700, as well as a host of other layers. None of our data uses another projection at present.

Thanks for the assistance with this. The whole CMV viewer is a great little app!

tr3vorm commented 10 years ago

@carey136 I have updated the projection widget to work with cmv 1.3.x but I have not been able to get custom basemaps working so I can test against them. I keep getting an error reported:

'Map.setBasemap: Unable to find basemap definition for: "nztopo". Try one of these: streets,satellite,hybrid,topo,gray,oceans,national-geographic,osm'

I have taken all except my basemap out of the config - do you have custom basemaps working with the cmv 1.3.0?

carey136 commented 10 years ago

I'm familiar with that error. We currently have a number of custom basemaps working with the 1.3, with the MapInfo widget working fine too. I'll try and replicate the error in the morning and dig out the solution. I remember having to include the basemap in Basemaps.js, as well as viewer.js, remembering to include the title (nztopo) in the list of other basemaps at the top of viewer.js.

The difference with our configuration was that we defined an extend and spatial references with each new basemap added.

I can include a copy of our configuration if desired when I get back to the office, or we could open a separate issue for this?

tr3vorm commented 10 years ago

I had managed to get it working (trial and error) more or less as you described, but don't have it working as well as it should. I also managed to get the projection widget working with the custom basemap - a temporary fix is just to add the line

this.baseProjection = proj4.defs(this.proj4Catalog + ':' +String(this.map.spatialReference.wkid));

at line 141 in the most recent Projection.js (updated today)

Yes, I think the custom basemap config needs to be raised as an issue, or at least documented.

carey136 commented 10 years ago

It appears i've misinterpreted things along the line here. I hadn't got the widget you developed to work yet (though I suspect with the edit you've made It will now). I was thinking of the MapInfo widget coordinates reported in the bottom left of the map, which seems to honour the current custom projection by default.

I'll try adding the projection widget to my app today.

As for the custom, basemaps, I've reproduced our custom basemaps without issue in 1.3.x

This involved editing basemaps.js:

1 < Uncommenting the first functions- Basemap, BasemapLayer, osm 2 < Mode: 'custom', 3 < mapStartBasemap: 'mybasemap' 4 < basemapsToShow: ['mybasemap', 'streets'......], 5 < Comment out all AGOL Basemaps (line 17-40) 6 < add custom basemap - e.g.

mybasemap: { title: 'Basemaps', basemap: new Basemap({ id: 'mybasemap', layers: [new BasemapLayer({ url: 'http://myserver/ArcGIS/rest/services/mybasemap/MapServer' })] }) },

And the editing of Viewer.js:

1 < Add Basemap and BasemapLayer functions at start of file 2 < Add custom Basemap with the following format (the use of showAttribution includes copyright text from the web service, and attribution width was included as our attribution is quite long).

mapOptions: { basemap: new Basemap({ id: 'mybasemap', layers: [new BasemapLayer({ url: 'http://myserver/ArcGIS/rest/services/mybasemap/MapServer' })] }), zoom: 5, showAttribution: true, attributionWidth: 50 },

This method worked for all or our tiled map services, as well as the example services commented out in basemaps.js. Any further maps to be added to the basemaps drop down menu need only be added in basemaps.js I feel like the use of basemap: new Basemap in Viewer may be duplicating the mapping at some point, but importantly it works properly this way.

carey136 commented 10 years ago

I can also now verify that the projection widget works perfectly with British National Grid and WGS84, negating the use of the coordinate feature in the measure widget (and allowing the zoom to point function as well).

It's not a direct solution to the issue I started with, but I feel this is a welcome compromise. Unless there is anything left to add, i'll close this issue.

tr3vorm commented 10 years ago

Many thanks for the basemap config info. I never got the widget going, but now I realise why.

I updated the projection widget after my last post above, with a more elegant solution (but not a new release). No changes in terms of functionality except that my temporary fix above won't handle the AGOL web-mercator maps.

The projection widget has some odd behaviour with regard to displaying the grid that needs to be sorted out. I also need to handle the new open/close widget events to restore the default mapClickMode. This was my first project in dojo/cmv and it was a steep learning curve (for me). I borrowed code from the mapinfo and streetview widgets. Anyway, plenty of room for improvement but glad it is working for you!

PS. It would be worthwhile including the custom basemap config in the Wiki

tmcgee commented 10 years ago

The custom basemap config is included in the wiki here. If there's something new in this issue that is not covered on that wiki page, please add it.

carey136 commented 10 years ago

@tmcgee To be honest I should have pointed @tr3vorm to the wiki first. It is exactly the same as the steps recommended in the on the customizing basemaps.js page. Nothing more needs to be added.

The only change I'd made was the inclusion of attributes, which is now also documented in the wiki, so all is well.

Thanks again guys