OpenLayers, Bing and KML
I am trying to lay KML on top of VirtualEarth Map in OpenLayers but it doesn't work. I guess it must be something with a projection.
Map:
var options = {
controls: [ new OpenLayers.Control.KeyboardDefaults(),
new OpenLayers.Control.MouseDefaults(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.LayerSwitcher()
],
maxExtent: new OpenLayers.Bounds( -200000, -200000, 200000, 200000),
numZoomLevels: 19,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
sphericalMercator: true
};
map = new OpenLayers.Map("map", options);
var binghybrid = new OpenLayers.Layer.VirtualEarth("Hybrid", {
type: VEMapStyle.Hybrid
});
KML:
var animals = new OpenLayers.Layer.Vector("Animals", {
projection: new OpenLayers.Projection("EPSG:4326"),
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "kml/animals.kml",
format: new OpenLayers.Format.KML({
extractStyles: true,
extractAttributes: true
})
})
});
Anyone ?! Thanks.
a source to share
I found the answer in this document: http://docs.openlayers.org/library/spherical_mercator.html
Edit Example: http://openlayers.org/dev/examples/spherical-mercator.html
The key is in:
var in_options = {
'internalProjection': new OpenLayers.Projection("EPSG:900913"),
'externalProjection': new OpenLayers.Projection("EPSG:4326")
};
var kmlOptionsIn = OpenLayers.Util.extend({ extractStyles: false },in_options);
var features = new OpenLayers.Format.KML(kmlOptionsIn).read(kml);
Here is a complete source for an example. (just copy / paste in html file, download and click the "Add KML" button).
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="js/OpenLayers/theme/default/style.css" type="text/css" />
<script src='http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1'></script>
<script src="js/OpenLayers/OpenLayers.js"></script>
<script type="text/javascript">
var lon = 5;
var lat = 40;
var zoom = 5;
var map, layer, vectors, formats;
function init() {
var options = {
units: "m",
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
restrictedExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
};
map = new OpenLayers.Map('map', options);
var hybrid = new OpenLayers.Layer.VirtualEarth("Bing Base Map",
{
sphericalMercator: true,
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
});
var venctor_options = {
units: "m",
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
restrictedExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
};
vectors = new OpenLayers.Layer.Vector("Vector Layer", venctor_options);
map.addControl(new OpenLayers.Control.MousePosition());
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addLayers([hybrid, vectors]);
map.zoomToMaxExtent();
// var center = new OpenLayers.LonLat(-30, 12);
// map.setCenter(center, 1);
}
function deserialize() {
var kml = "<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://www.opengis.net/kml/2.2'><Document><name>Granules</name><description>Exported on Wed Nov 24 2010 09:41:38 GMT-0500 (Eastern Standard Time)</description><Placemark><name>GRAN-46</name><description>{ ID:46, TYPE:'OPT', START_DATE:'7/23/2003 4:21:17 PM', END_DATE:'7/23/2003 4:22:13 PM', INGESTDATE:'3/25/2004 12:00:00 AM', EXTERNAL_ID:null, PIXELS:6000, LINES:37494, DATA_PRODIVER_ID:1, COMMENTS:'null' }</description><Polygon><outerBoundaryIs><LinearRing id=''><coordinates>-81.2162649929523,31.1248919963837 -81.177305996418,31.2556949853897 -81.0197220146656,31.781594991684 -80.8606449961662,32.3073099851608 -80.7000299990177,32.8328340053558 -80.5378299951553,33.3581640124321 -80.3739939928055,33.8832920193672 -80.2084729969502,34.4082159996033 -80.8601450026035,34.515996992588 -81.0217449963093,33.9903180003166 -81.18175598979,33.4644510149956 -81.3402259945869,32.9384009838104 -81.4972029924393,32.412172973156 -81.6527320146561,31.8857709765434 -81.8068569898605,31.359197974205 -81.8449699878693,31.2282310128212 -81.2162649929523,31.1248919963837 </coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark></Document></kml>"
var type = "kml";
var in_options = {
'internalProjection': new OpenLayers.Projection("EPSG:900913"),
'externalProjection': new OpenLayers.Projection("EPSG:4326")
};
var kmlOptionsIn = OpenLayers.Util.extend({ extractStyles: false },in_options);
var features = new OpenLayers.Format.KML(kmlOptionsIn).read(kml);
var bounds;
if (features) {
if (features.constructor != Array) {
features = [features];
}
for (var i = 0; i < features.length; ++i) {
if (!bounds) {
bounds = features[i].geometry.getBounds();
} else {
bounds.extend(features[i].geometry.getBounds());
}
}
vectors.addFeatures(features);
map.zoomToExtent(bounds);
}
}
</script>
<style type="text/css">
/**
* CSS Reset
* From Blueprint reset.css
* http://blueprintcss.googlecode.com
*/
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
body {line-height:1.5;}
table {border-collapse:separate;border-spacing:0;}
caption, th, td {text-align:left;font-weight:normal;}
table, td, th {vertical-align:middle;}
blockquote:before, blockquote:after, q:before, q:after {content:"";}
blockquote, q {quotes:"" "";}
a img {border:none;}
/**
* Basic Typography
*/
body {
font-family: "Lucida Grande", Verdana, Geneva, Lucida, Arial, Helvetica, sans-serif;
font-size: 80%;
color: #222;
background: #fff;
margin: 1em 1.5em;
}
pre, code {
margin: 1.5em 0;
white-space: pre;
}
pre, code {
font: 1em 'andale mono', 'lucida console', monospace;
line-height:1.5;
}
a[href] {
color: #436976;
background-color: transparent;
}
h1, h2, h3, h4, h5, h6 {
color: #003a6b;
background-color: transparent;
font: 100% 'Lucida Grande', Verdana, Geneva, Lucida, Arial, Helvetica, sans-serif;
margin: 0;
padding-top: 0.5em;
}
h1 {
font-size: 130%;
margin-bottom: 0.5em;
border-bottom: 1px solid #fcb100;
}
h2 {
font-size: 120%;
margin-bottom: 0.5em;
border-bottom: 1px solid #aaa;
}
h3 {
font-size: 110%;
margin-bottom: 0.5em;
text-decoration: underline;
}
h4 {
font-size: 100%;
font-weight: bold;
}
h5 {
font-size: 100%;
font-weight: bold;
}
h6 {
font-size: 80%;
font-weight: bold;
}
/**
* Map Examples Specific
*/
.smallmap {
width: 800px;
height: 600px;
border: 1px solid #ccc;
}
#tags {
display: none;
}
#docs p {
margin-bottom: 0.5em;
}
</style>
</head>
<body onload="init()">
<h1 id="title">KML Layer Example</h1>
<div id="tags">
KML
</div>
<p id="shortdesc">
Demonstrates loading and displaying a KML file on top of a basemap. <button onclick="deserialize()">Add KML</button>
</p>
<div id="map" class="smallmap"></div>
<div id="docs"></div>
</body>
</html>
a source to share
KML and Bing maps must work with the same projection and coordinate system. Have you tried setting them up the same way? This is in addition to Thqr's recommendation about addLayers (since you have a piece of code, it is not clear if you are doing this or not)
In general, OpenLayers can do vector data reprogramming, but you also need to include the Proj4JS library.
a source to share
Please take the trouble that I am using the OpenLayers example by a previous programmer. But I've made some innovative changes that are even better. For now, I highly recommend that you use Google Maps. Here I am simplifying JavaScript where you can put in the main tag:
<script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAl9RMqSzhPUXAfeBCXOussRTQDbvAygy0cfGJr8dEMAYKf3RWNBQqP9mjKIsqTfmAlz5LOJ3Xpy5s4w'></script>
Then you can insert Google Maps into OpenLayers like this:
<script type="text/javascript">
var lon = 5;
var lat = 40;
var zoom = 5;
var map, layer, vectors, formats;
function init() {var options = {
units: "m",
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
restrictedExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
};
map = new OpenLayers.Map('map', options);
var gmap = new OpenLayers.Layer.Google(
"Google Streets",
{
numZoomLevels: 20,
sphericalMercator: true,
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
});
var vector_options = {
units: "m",
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
restrictedExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
};
vectors = new OpenLayers.Layer.Vector("Vector Layer", vector_options);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addLayers([gmap, vectors]);
map.zoomToMaxExtent();
}
</script>
I'm just happy to help. Good luck!
a source to share