Two New Data Modules for Bing Maps V7

 

By Ricky Brundritt, EMEA Bing Maps Technology Solution Professional

In September of 2011 we started the Bing Maps v7 Module CodePlex Project. The purpose of this project is to create a centralized location where developers could find and share useful modules that expand the functionality of the Bing Maps V7 API. Since the start of the project, we’ve had 15 modules submitted.

Today, I would like to highlight the two newest modules added to the project and provide a few updates to existing modules.

GeoJSON Module

Download here

This module was created by Brian Norman a Microsoft Bing Maps MVP from Earthware Ltd.

This module allows you to import GeoJSON files into Bing Maps. A GeoJSON feed will be downloaded and parsed into an EntityCollection which can then be added to the map. Additional properties are captured and stored in a Metadata tag on each shape making it easy to relate shapes to their metadata.

GeoJSON is a data format standard used for representing geospatial objects in JSON (JavaScript Object notation). JSON is much more compact than XML which makes it a great format for sharing spatial data online. In fact the AJAX Map DataConnector uses GeoJSON to send spatial data from SQL Server to Bing Maps.

Well Known Text Reader/Writer Module

Download here

I created this module because I wanted a simple tool for quickly visualizing Well Known Text on Bing Maps. This module allows you to easily read and write Well Know Text data from Bing Maps. When reading Well Known Text data it is parsed into Bing Maps shapes; MultiPoint, MultiLinstring, MultiPolygon and GeometryCollection are turned into an EntityCollection of shapes. To write Well Known Text simply pass in a Bing Maps shape and the Well Known Text equivalent will be returned.

clip_image004

Well Known Text (WKT) is an OGC (Open Geospatial Consortium) standard for representing Geospatial Data. In fact WKT is supported by the spatial types in Microsoft SQL Server 2008 and above as well as SQL Azure.

*Project Idea: Combine this module with the Shape Toolbox Module and make it easy for your users to draw on the map and upload the shape data into Microsoft SQL Server.

*Demo Tip: Use this module to quickly create demos that render complex spatial data. Simply store your Well Known Text in a JavaScript file as a string to save time setting up a web service to connect to your database. Note: this approach is not recommended for production applications as loading all the spatial data via a JavaScript file can make for slow loading of your application.

Other Data Related Modules

GeoRSS Module – GeoRSS is a common XML file format for sharing spatial data as a syndication feed. This module also supports GML, an OGC compliant XML format. This module has been updated to support Complex Polygons (polygons with holes).

GPX Module – GPX is a common XML data format that is used by GPS devices. Many GPS devices allow you to stave points, routes and tracks which can then be exported from the device in GPX format. This module makes it easy to view these files on Bing Maps.

Bing Maps v7 AJAX control Infobox positioning

In the Bing Maps v7 AJAX control, when you open an infobox it will open up where it is positioned. If you are near the edges of the map it will go beyond the edges and end up getting cut of, out of view as the infobox is within the map div which hides any overflowing elements. Here is an example.

infobox1

This might not be the ideal default case, but Bing Maps is developed in such a way that it tries to give you the basic use case and all the tools needed to create the experience you want. One way around this is to use the Custom Infobox Control module for Bing Maps that will change the direction of the infobox so that it appears towards the center of the map. This works well in some cases, but completely ignores the built in infobox control and requires jQuery.

For those migrating from Multimap you may prefer the map to reposition so that the infobox comes into view. This is a user experience that others would prefer as the infobox will always render in the same way. The following code uses the built in infobox properties to determine if the infobox needs to be repositioned and if it does it moves the map so that the infobox comes into view.

[php]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>

<script type="text/javascript">
var map = null;
var pinLayer, pinInfobox;

function GetMap() {
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById("myMap"), { credentials: "YOUR_BING_MAPS_KEY", zoom: 5 });

//Create two layers, one for pushpins, the other for the infobox. This way the infobox will always be above the pushpins.
pinLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(pinLayer);

var infoboxLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(infoboxLayer);

// Create the info box for the pushpin
pinInfobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false });
infoboxLayer.push(pinInfobox);

//Create a test pushpiin
var pin = new Microsoft.Maps.Pushpin(map.getCenter());
pin.Title = ‘This is pin 1’;
pin.Description = ‘Pan map so pin is at edge and then click on pin.’;

Microsoft.Maps.Events.addHandler(pin, ‘click’, displayInfobox);
pinLayer.push(pin);
}

function displayInfobox(e) {
if (e.targetType == "pushpin") {
pinInfobox.setOptions({ title: e.target.Title, description: e.target.Description, visible: true, offset: new Microsoft.Maps.Point(0, 25) });
pinInfobox.setLocation(e.target.getLocation());

//A buffer limit to use to specify the infobox must be away from the edges of the map.
var buffer = 25;

var infoboxOffset = pinInfobox.getOffset();
var infoboxAnchor = pinInfobox.getAnchor();
var infoboxLocation = map.tryLocationToPixel(e.target.getLocation(), Microsoft.Maps.PixelReference.control);

var dx = infoboxLocation.x + infoboxOffset.x – infoboxAnchor.x;
var dy = infoboxLocation.y – 25 – infoboxAnchor.y;

if (dy < buffer) { //Infobox overlaps with top of map.
//Offset in opposite direction.
dy *= -1;

//add buffer from the top edge of the map.
dy += buffer;
} else {
//If dy is greater than zero than it does not overlap.
dy = 0;
}

if (dx < buffer) { //Check to see if overlapping with left side of map.
//Offset in opposite direction.
dx *= -1;

//add a buffer from the left edge of the map.
dx += buffer;
} else { //Check to see if overlapping with right side of map.
dx = map.getWidth() – infoboxLocation.x + infoboxAnchor.x – pinInfobox.getWidth();

//If dx is greater than zero then it does not overlap.
if (dx > buffer) {
dx = 0;
} else {
//add a buffer from the right edge of the map.
dx -= buffer;
}
}

//Adjust the map so infobox is in view
if (dx != 0 || dy != 0) {
map.setView({ centerOffset: new Microsoft.Maps.Point(dx, dy), center: map.getCenter() });
}
}
}
</script>
</head>
<body onload="GetMap();">
<div id=’myMap’ style="position:relative; width:600px; height:400px;"></div>
</html>
[/php]

When you load this code into a browser a pushpin will appear in the center of the map. Pan the map so that the infobox is near one of the edges. When you click on the pushpin to open the infobox you will see the map reposition such that the infobox comes into view. The example below is the result of opening the infobox when the pushpin was in the top right corner of the map.