none
Get GeoJSON map.entities object reference from a map click RRS feed

  • Question

  • This has got to be the most elementary question in all of digital mapping, but here goes. I have an EntityCollection, 'map.entities', that has been populated from a Microsoft.Maps.GeoJson.readFromUrl call. The point objects display fine on the map, and I can access the point collection's attributes (ID#, type of point, etc.) from a map.entities.get(index-number) call. How do I perform the equivalent of a map.entities.get(the-index-number-from-a-clicked-map-position) call? 

    Wednesday, June 29, 2016 3:49 PM

Answers

  • Can you provide a bit more details, it's not clear on what you are trying to achieve? If you want to add a click event to a pushpin, then either add the event directly to the pushpin, or use the new Layer class and add the event to that. The event handler will return a reference to the pushpin. If you add the event directly to the pushpin, and the event handler has a e property, then use e.target to get to pushpin reference. If the pushpin is in a Layer, then use e.primitive. Here are a few pieces of documentation around this:

    https://msdn.microsoft.com/en-us/library/mt750265.aspx

    https://msdn.microsoft.com/en-us/library/mt750272.aspx

    https://msdn.microsoft.com/en-us/library/mt750277.aspx

    https://msdn.microsoft.com/en-US/library/mt712656.aspx

    Personally I would recommend creating a Layer adding it to the map using map.layers.insert, then passing your GeoJSON data into that. Then you only need to create a single event handler on the layer itself. the code will be able the same length as adding an event to each pushpin, but since there is only one event handler there will be a slight performance benefit.


    [Blog] [twitter] [LinkedIn]

    Wednesday, June 29, 2016 5:02 PM
  • The map.entities property doesn't have a click event. You can either add a click event to each shape or to a Layer class. Here is a sample that does this for a layer.

    <!DOCTYPE html>
    <html>
    <head>
    	<title>geoJsonReadExternalHTML</title>
    	<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
    </head>
    <body>
    	<div id='myMap' style='width: 100vw; height: 100vh;'></div>
    	<script type='text/javascript'>
    		function loadMapScenario() {
    			var myMap;
    			var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
    				credentials: 'Bing Maps Key',
    				zoom: 12
    			});
    			myMap = map;
    			infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
    				title: 'Popup',
    				description: 'Description',
    				visible: false
    			});
    			infobox.setMap(map);
    			
    			var dataLayer = new Microsoft.Maps.Layer();
    			map.layers.insert(dataLayer);
    			
    			Microsoft.Maps.loadModule('Microsoft.Maps.GeoJson', function () {
    				Microsoft.Maps.GeoJson.readFromUrl('http://96.127.59.220:8080/geoserver/opengeo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=opengeo:Signs_4326&maxFeatures=5000&outputFormat=application%2Fjson', function (shapes) {
    					dataLayer.add(shapes); 
    
    				Microsoft.Maps.Events.addHandler(dataLayer, 'click', pointClicked);
    				function pointClicked(e) {
    				
    					var clickedShape = e.primitive;
    					var shapeInfo = clickedShape.metadata;
    
    					infobox.setOptions({
    						//Use the location of where the mouse was clicked to position the infobox.
    						location: e.location,
    						visible: true
    						})
    				}
    				});
    			});
    		}
    	</script>
    	<script src='http://www.bing.com/api/maps/mapcontrol?branch=release&callback=loadMapScenario' async defer></script>
    </body>
    </html>


    [Blog] [twitter] [LinkedIn]

    Thursday, June 30, 2016 2:16 AM
  • set the title and description properties of the infobox using the setOptions function. Here is a sample: http://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk#reuseInfobox+JS

    [Blog] [twitter] [LinkedIn]

    Wednesday, March 15, 2017 3:35 PM

All replies

  • Can you provide a bit more details, it's not clear on what you are trying to achieve? If you want to add a click event to a pushpin, then either add the event directly to the pushpin, or use the new Layer class and add the event to that. The event handler will return a reference to the pushpin. If you add the event directly to the pushpin, and the event handler has a e property, then use e.target to get to pushpin reference. If the pushpin is in a Layer, then use e.primitive. Here are a few pieces of documentation around this:

    https://msdn.microsoft.com/en-us/library/mt750265.aspx

    https://msdn.microsoft.com/en-us/library/mt750272.aspx

    https://msdn.microsoft.com/en-us/library/mt750277.aspx

    https://msdn.microsoft.com/en-US/library/mt712656.aspx

    Personally I would recommend creating a Layer adding it to the map using map.layers.insert, then passing your GeoJSON data into that. Then you only need to create a single event handler on the layer itself. the code will be able the same length as adding an event to each pushpin, but since there is only one event handler there will be a slight performance benefit.


    [Blog] [twitter] [LinkedIn]

    Wednesday, June 29, 2016 5:02 PM
  • Thank you, Ricky. Here is the code:

    <!DOCTYPE html>
    <html>
    <head>
    	<title>geoJsonReadExternalHTML</title>
    	<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
    </head>
    <body>
    	<div id='myMap' style='width: 100vw; height: 100vh;'></div>
    	<script type='text/javascript'>
    		function loadMapScenario() {
    			var myMap;
    			var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
    				credentials: 'Bing Maps Key',
    				zoom: 12
    			});
    			myMap = map;
    			infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
    				title: 'Popup',
    				description: 'Description',
    				visible: false
    			});
    			infobox.setMap(map);
    			Microsoft.Maps.loadModule('Microsoft.Maps.GeoJson', function () {
    				Microsoft.Maps.GeoJson.readFromUrl('http://96.127.59.220:8080/geoserver/opengeo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=opengeo:Signs_4326&maxFeatures=5000&outputFormat=application%2Fjson', function (shapes) {
    					map.entities.push(shapes); 
    				Microsoft.Maps.Events.addHandler(map.entities, 'click', pointClicked);
    				function pointClicked(e) {
    					infobox.setOptions({
    						//Use the location of where the mouse was clicked to position the infobox.
    						location: e.location,
    						visible: true
    						})
    				}
    				});
    			});
    		}
    	</script>
    	<script src='http://www.bing.com/api/maps/mapcontrol?branch=release&callback=loadMapScenario' async defer></script>
    </body>
    </html>
    

    The point objects in the map.entities array each have several fields with associated data (they are street signs with attributes like sign type, color, reflectivity, etc). Line 30 correctly reads the map location of the pick event-- what I need is (hopefully) a function call that returns the point's index in the map.entities array. Is there not an easy way to do this?

    Thank you,

    Rudy Stricklan

    Thursday, June 30, 2016 1:33 AM
  • The map.entities property doesn't have a click event. You can either add a click event to each shape or to a Layer class. Here is a sample that does this for a layer.

    <!DOCTYPE html>
    <html>
    <head>
    	<title>geoJsonReadExternalHTML</title>
    	<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
    </head>
    <body>
    	<div id='myMap' style='width: 100vw; height: 100vh;'></div>
    	<script type='text/javascript'>
    		function loadMapScenario() {
    			var myMap;
    			var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
    				credentials: 'Bing Maps Key',
    				zoom: 12
    			});
    			myMap = map;
    			infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
    				title: 'Popup',
    				description: 'Description',
    				visible: false
    			});
    			infobox.setMap(map);
    			
    			var dataLayer = new Microsoft.Maps.Layer();
    			map.layers.insert(dataLayer);
    			
    			Microsoft.Maps.loadModule('Microsoft.Maps.GeoJson', function () {
    				Microsoft.Maps.GeoJson.readFromUrl('http://96.127.59.220:8080/geoserver/opengeo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=opengeo:Signs_4326&maxFeatures=5000&outputFormat=application%2Fjson', function (shapes) {
    					dataLayer.add(shapes); 
    
    				Microsoft.Maps.Events.addHandler(dataLayer, 'click', pointClicked);
    				function pointClicked(e) {
    				
    					var clickedShape = e.primitive;
    					var shapeInfo = clickedShape.metadata;
    
    					infobox.setOptions({
    						//Use the location of where the mouse was clicked to position the infobox.
    						location: e.location,
    						visible: true
    						})
    				}
    				});
    			});
    		}
    	</script>
    	<script src='http://www.bing.com/api/maps/mapcontrol?branch=release&callback=loadMapScenario' async defer></script>
    </body>
    </html>


    [Blog] [twitter] [LinkedIn]

    Thursday, June 30, 2016 2:16 AM
  • As usual, right on the money, Ricky. Works like a charm. Thanks again!
    Friday, July 1, 2016 1:48 AM
  • Does the metadata refer to a specific properties member called metadata?Could you share what the GeoJSON metadata for the InfoBox looks like? 

    I'm looking at the GeoJSON Format Specification and only see a specific way to add the geometry and random properties.  I need to include images and descriptions with each point. I'm trying to build the GeoJSON message itself that includes all this information in addition to the geometry. 

    
    Thursday, November 17, 2016 7:12 PM
  • Never mind.  I can see the metadata as long as I pass it as properties.
    Monday, November 21, 2016 5:07 PM
  • How do you populate the infobox? 

    Here's a snippet of the geojson:

    {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"OBJECTID":25,"ID":"CAM00080","Title":"MF/HODGES DR WEBCAM - CAM080","Direction":"NW","href":"http://trafficam.mainroads.wa.gov.au/ViewCamera.asp?CameraNo=WB080"},"geometry":{"type":"Point","coordinates":[115.76402900000005,-31.755038999155115]}},

    Wednesday, March 15, 2017 8:25 AM
  • set the title and description properties of the infobox using the setOptions function. Here is a sample: http://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk#reuseInfobox+JS

    [Blog] [twitter] [LinkedIn]

    Wednesday, March 15, 2017 3:35 PM