Merge pull request #1368 from twpayne/vector-api-kml
[vector-api] ol.format.KML
This commit is contained in:
9391
examples/data/kml/2012-02-10.kml
Normal file
9391
examples/data/kml/2012-02-10.kml
Normal file
File diff suppressed because one or more lines are too long
@@ -104,13 +104,13 @@
|
||||
</Style>
|
||||
<Folder>
|
||||
<name>Paths</name>
|
||||
<visibility>0</visibility>
|
||||
<visibility>1</visibility>
|
||||
<description>Examples of paths. Note that the tessellate tag is by default
|
||||
set to 0. If you want to create tessellated lines, they must be authored
|
||||
(or edited) directly in KML.</description>
|
||||
<Placemark>
|
||||
<name>Tessellated</name>
|
||||
<visibility>0</visibility>
|
||||
<visibility>1</visibility>
|
||||
<description><![CDATA[If the <tessellate> tag has a value of 1, the line will contour to the underlying terrain]]></description>
|
||||
<LookAt>
|
||||
<longitude>-112.0822680013139</longitude>
|
||||
@@ -128,7 +128,7 @@
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Untessellated</name>
|
||||
<visibility>0</visibility>
|
||||
<visibility>1</visibility>
|
||||
<description><![CDATA[If the <tessellate> tag has a value of 0, the line follow a simple straight-line path from point to point]]></description>
|
||||
<LookAt>
|
||||
<longitude>-112.0822680013139</longitude>
|
||||
@@ -146,7 +146,7 @@
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Absolute</name>
|
||||
<visibility>0</visibility>
|
||||
<visibility>1</visibility>
|
||||
<description>Transparent purple line</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2719329043177</longitude>
|
||||
@@ -175,7 +175,7 @@
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Absolute Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<visibility>1</visibility>
|
||||
<description>Transparent green wall with yellow outlines</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2643334742529</longitude>
|
||||
@@ -205,7 +205,7 @@
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative</name>
|
||||
<visibility>0</visibility>
|
||||
<visibility>1</visibility>
|
||||
<description>Black line (10 pixels wide), height tracks terrain</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2580438551384</longitude>
|
||||
@@ -234,7 +234,7 @@
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<visibility>1</visibility>
|
||||
<description>Opaque blue walls with red outline, height tracks terrain</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2683594333433</longitude>
|
||||
@@ -265,7 +265,7 @@
|
||||
<Placemark>
|
||||
<name>Blue Icon</name>
|
||||
<description>Just another blue icon.</description>
|
||||
<styleUrl>data/kml/styles.kml#blueIcons</styleUrl>
|
||||
<styleUrl>styles.kml#blueIcons</styleUrl>
|
||||
<Point>
|
||||
<coordinates>-112.292238941097,36.09520916122063,630</coordinates>
|
||||
</Point>
|
||||
@@ -273,7 +273,7 @@
|
||||
<Placemark>
|
||||
<name>Sun Icon</name>
|
||||
<description>Just another sun icon.</description>
|
||||
<styleUrl>data/kml/styles.kml#sunIconMap</styleUrl>
|
||||
<styleUrl>styles.kml#sunIconMap</styleUrl>
|
||||
<Point>
|
||||
<coordinates>-112.292238941097,36.15520916122063,630</coordinates>
|
||||
</Point>
|
||||
|
||||
56
examples/drag-and-drop.html
Normal file
56
examples/drag-and-drop.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>Drag-and-Drop example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span4">
|
||||
<h4 id="title">Drag-and-Drop example</h4>
|
||||
<p id="shortdesc">Example of using the drag-and-drop interaction. Drag and drop KML files on to the map.</p>
|
||||
<div id="docs">
|
||||
<p>See the <a href="drag-and-drop.js" target="_blank">drag-and-drop.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">drag-and-drop, kml</div>
|
||||
</div>
|
||||
<div class="span4 offset4">
|
||||
<div id="info" class="alert alert-success">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="jquery.min.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=drag-and-drop" type="text/javascript"></script>
|
||||
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
60
examples/drag-and-drop.js
Normal file
60
examples/drag-and-drop.js
Normal file
@@ -0,0 +1,60 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.RendererHint');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.format.KML');
|
||||
goog.require('ol.interaction');
|
||||
goog.require('ol.interaction.DragAndDrop');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.BingMaps');
|
||||
|
||||
|
||||
var map = new ol.Map({
|
||||
interactions: ol.interaction.defaults().extend([
|
||||
new ol.interaction.DragAndDrop({
|
||||
formatConstructors: [
|
||||
ol.format.KML
|
||||
]
|
||||
})
|
||||
]),
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.BingMaps({
|
||||
imagerySet: 'Aerial',
|
||||
key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3'
|
||||
})
|
||||
})
|
||||
],
|
||||
renderer: ol.RendererHint.CANVAS,
|
||||
target: 'map',
|
||||
view: new ol.View2D({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
var displayFeatureInfo = function(pixel) {
|
||||
var features = [];
|
||||
map.forEachFeatureAtPixel(pixel, function(feature, layer) {
|
||||
features.push(feature);
|
||||
});
|
||||
if (features.length > 0) {
|
||||
var info = [];
|
||||
var i, ii;
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
info.push(features[i].get('name'));
|
||||
}
|
||||
document.getElementById('info').innerHTML = info.join(', ') || ' ';
|
||||
} else {
|
||||
document.getElementById('info').innerHTML = ' ';
|
||||
}
|
||||
};
|
||||
|
||||
$(map.getViewport()).on('mousemove', function(evt) {
|
||||
var pixel = map.getEventPixel(evt.originalEvent);
|
||||
displayFeatureInfo(pixel);
|
||||
});
|
||||
|
||||
map.on('singleclick', function(evt) {
|
||||
var pixel = evt.getPixel();
|
||||
displayFeatureInfo(pixel);
|
||||
});
|
||||
75
examples/kml-earthquakes.html
Normal file
75
examples/kml-earthquakes.html
Normal file
@@ -0,0 +1,75 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>Earthquakes in KML</title>
|
||||
<style>
|
||||
#map {
|
||||
position: relative;
|
||||
}
|
||||
#info {
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
z-index: 100;
|
||||
}
|
||||
.tooltip.in {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.tooltip.top .tooltip-arrow {
|
||||
border-top-color: white;
|
||||
}
|
||||
.tooltip-inner {
|
||||
border: 2px solid white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"><div id="info"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span12">
|
||||
<h4 id="title">Earthquakes in KML</h4>
|
||||
<p id="shortdesc">Demonstrates the use of a Shape symbolizer to render earthquake locations.</p>
|
||||
<div id="docs">
|
||||
<p>
|
||||
This example parses a KML file and renders the features as a vector layer. The layer is given a <code>styleFunction</code> that renders earthquake locations with a size relative to their magnitude.
|
||||
</p>
|
||||
<p>See the <a href="kml-earthquakes.js" target="_blank">kml-earthquakes.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">KML, vector, style</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="jquery.min.js" type="text/javascript"></script>
|
||||
<script src="../resources/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=kml-earthquakes" type="text/javascript"></script>
|
||||
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
96
examples/kml-earthquakes.js
Normal file
96
examples/kml-earthquakes.js
Normal file
@@ -0,0 +1,96 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.RendererHint');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.KML');
|
||||
goog.require('ol.source.Stamen');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
var styleCache = {};
|
||||
var styleFunction = function(feature, resolution) {
|
||||
// 2012_Earthquakes_Mag5.kml stores the magnitude of each earthquake in a
|
||||
// standards-violating <magnitude> tag in each Placemark. We extract it from
|
||||
// the Placemark's name instead.
|
||||
var name = feature.get('name');
|
||||
var magnitude = parseFloat(name.substr(2));
|
||||
var radius = 5 + 20 * (magnitude - 5);
|
||||
var style = styleCache[radius];
|
||||
if (!style) {
|
||||
style = [new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: radius,
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255, 153, 0, 0.4)'
|
||||
}),
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgba(255, 204, 0, 0.2)',
|
||||
width: 1
|
||||
})
|
||||
})
|
||||
})];
|
||||
styleCache[radius] = style;
|
||||
}
|
||||
return style;
|
||||
};
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.KML({
|
||||
reprojectTo: 'EPSG:3857',
|
||||
url: 'data/kml/2012_Earthquakes_Mag5.kml'
|
||||
}),
|
||||
styleFunction: styleFunction
|
||||
});
|
||||
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.Stamen({
|
||||
layer: 'toner'
|
||||
})
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
renderer: ol.RendererHint.CANVAS,
|
||||
target: 'map',
|
||||
view: new ol.View2D({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
var info = $('#info');
|
||||
info.tooltip({
|
||||
animation: false,
|
||||
trigger: 'manual'
|
||||
});
|
||||
|
||||
var displayFeatureInfo = function(evt) {
|
||||
var pixel = map.getEventPixel(evt.originalEvent);
|
||||
info.css({
|
||||
left: pixel[0] + 'px',
|
||||
top: (pixel[1] - 15) + 'px'
|
||||
});
|
||||
var feature = map.forEachFeatureAtPixel(pixel, function(feature, layer) {
|
||||
return feature;
|
||||
});
|
||||
if (feature) {
|
||||
info.tooltip('hide')
|
||||
.attr('data-original-title', feature.get('name'))
|
||||
.tooltip('fixTitle')
|
||||
.tooltip('show');
|
||||
} else {
|
||||
info.tooltip('hide');
|
||||
}
|
||||
};
|
||||
|
||||
$(map.getViewport()).on('mousemove', function(evt) {
|
||||
displayFeatureInfo(evt);
|
||||
});
|
||||
|
||||
map.on('singleclick', function(evt) {
|
||||
displayFeatureInfo(evt);
|
||||
});
|
||||
63
examples/kml-timezones.html
Normal file
63
examples/kml-timezones.html
Normal file
@@ -0,0 +1,63 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>Timezones in KML</title>
|
||||
<style>
|
||||
#map {
|
||||
position: relative;
|
||||
}
|
||||
#info {
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"><div id="info"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span12">
|
||||
<h4 id="title">Timezones in KML</h4>
|
||||
<p id="shortdesc">Demonstrates rendering timezones from KML.</p>
|
||||
<div id="docs">
|
||||
<p>This example parses a KML file and renders the features as a vector layer. The layer is given a <code>ol.style.Style</code> that fills timezones yellow with an opacity calculated based on the current offset to local noon.</p>
|
||||
<p>See the <a href="kml-timezones.js" target="_blank">kml-timezones.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">KML, vector, style</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="jquery.min.js" type="text/javascript"></script>
|
||||
<script src="../resources/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=kml-timezones" type="text/javascript"></script>
|
||||
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
102
examples/kml-timezones.js
Normal file
102
examples/kml-timezones.js
Normal file
@@ -0,0 +1,102 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.RendererHint');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.KML');
|
||||
goog.require('ol.source.Stamen');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
/*
|
||||
* Compute the style of the feature. Here we want the opacity of polygons to
|
||||
* be based on the offset from local noon. For example, a timezone where it is
|
||||
* currently noon would have an opacity of 0.75. And a timezone where it is
|
||||
* currently midnight would have an opacity of 0. This doesn't account for
|
||||
* daylight savings, so don't use it to plan your vacation.
|
||||
*/
|
||||
var styleFunction = function(feature, resolution) {
|
||||
var offset = 0;
|
||||
var name = feature.get('name'); // e.g. GMT -08:30
|
||||
var match = name.match(/([\-+]\d{2}):(\d{2})$/);
|
||||
if (match) {
|
||||
var hours = parseInt(match[1], 10);
|
||||
var minutes = parseInt(match[2], 10);
|
||||
offset = 60 * hours + minutes;
|
||||
}
|
||||
var date = new Date();
|
||||
var local = new Date(date.getTime() +
|
||||
(date.getTimezoneOffset() + offset) * 60000);
|
||||
// offset from local noon (in hours)
|
||||
var delta = Math.abs(12 - local.getHours() + (local.getMinutes() / 60));
|
||||
if (delta > 12) {
|
||||
delta = 24 - delta;
|
||||
}
|
||||
var opacity = 0.75 * (1 - delta / 12);
|
||||
return [new ol.style.Style({
|
||||
fill: new ol.style.Fill({
|
||||
color: [0xff, 0xff, 0x33, opacity]
|
||||
}),
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#ffffff'
|
||||
})
|
||||
})];
|
||||
};
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.KML({
|
||||
url: 'data/kml/timezones.kml'
|
||||
}),
|
||||
styleFunction: styleFunction
|
||||
});
|
||||
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.Stamen({
|
||||
layer: 'toner'
|
||||
})
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
renderer: ol.RendererHint.CANVAS,
|
||||
target: 'map',
|
||||
view: new ol.View2D({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
var info = $('#info');
|
||||
info.tooltip({
|
||||
animation: false,
|
||||
trigger: 'manual'
|
||||
});
|
||||
|
||||
var displayFeatureInfo = function(evt) {
|
||||
var pixel = map.getEventPixel(evt.originalEvent);
|
||||
info.css({
|
||||
left: pixel[0] + 'px',
|
||||
top: (pixel[1] - 15) + 'px'
|
||||
});
|
||||
var feature = map.forEachFeatureAtPixel(pixel, function(feature, layer) {
|
||||
return feature;
|
||||
});
|
||||
if (feature) {
|
||||
info.tooltip('hide')
|
||||
.attr('data-original-title', feature.get('name'))
|
||||
.tooltip('fixTitle')
|
||||
.tooltip('show');
|
||||
} else {
|
||||
info.tooltip('hide');
|
||||
}
|
||||
};
|
||||
|
||||
$(map.getViewport()).on('mousemove', function(evt) {
|
||||
displayFeatureInfo(evt);
|
||||
});
|
||||
|
||||
map.on('singleclick', function(evt) {
|
||||
displayFeatureInfo(evt);
|
||||
});
|
||||
56
examples/kml.html
Normal file
56
examples/kml.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
|
||||
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>KML example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span4">
|
||||
<h4 id="title">KML example</h4>
|
||||
<p id="shortdesc">Example of using the KML source.</p>
|
||||
<div id="docs">
|
||||
<p>See the <a href="kml.js" target="_blank">kml.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">KML</div>
|
||||
</div>
|
||||
<div class="span4 offset4">
|
||||
<div id="info" class="alert alert-success">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="jquery.min.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=kml" type="text/javascript"></script>
|
||||
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
58
examples/kml.js
Normal file
58
examples/kml.js
Normal file
@@ -0,0 +1,58 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.RendererHint');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.BingMaps');
|
||||
goog.require('ol.source.KML');
|
||||
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.BingMaps({
|
||||
imagerySet: 'Aerial',
|
||||
key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3'
|
||||
})
|
||||
});
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.KML({
|
||||
reprojectTo: 'EPSG:3857',
|
||||
url: 'data/kml/2012-02-10.kml'
|
||||
})
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [raster, vector],
|
||||
renderer: ol.RendererHint.CANVAS,
|
||||
target: 'map',
|
||||
view: new ol.View2D({
|
||||
center: [876970.8463461736, 5859807.853963373],
|
||||
zoom: 10
|
||||
})
|
||||
});
|
||||
|
||||
var displayFeatureInfo = function(pixel) {
|
||||
var features = [];
|
||||
map.forEachFeatureAtPixel(pixel, function(feature, layer) {
|
||||
features.push(feature);
|
||||
});
|
||||
if (features.length > 0) {
|
||||
var info = [];
|
||||
var i, ii;
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
info.push(features[i].get('name'));
|
||||
}
|
||||
document.getElementById('info').innerHTML = info.join(', ') || ' ';
|
||||
} else {
|
||||
document.getElementById('info').innerHTML = ' ';
|
||||
}
|
||||
};
|
||||
|
||||
$(map.getViewport()).on('mousemove', function(evt) {
|
||||
var pixel = map.getEventPixel(evt.originalEvent);
|
||||
displayFeatureInfo(pixel);
|
||||
});
|
||||
|
||||
map.on('singleclick', function(evt) {
|
||||
var pixel = evt.getPixel();
|
||||
displayFeatureInfo(pixel);
|
||||
});
|
||||
@@ -260,6 +260,12 @@
|
||||
* Possible values are `barometric`, `gps`, and `none`. Default is `none`.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.format.KMLOptions
|
||||
* @property {boolean|undefined} extractAttributes Extract attributes.
|
||||
* @property {boolean|undefined} extractStyles Extract styles.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.interaction.DoubleClickZoomOptions
|
||||
* @property {number|undefined} duration Animation duration in milliseconds. Default is `250`.
|
||||
@@ -268,6 +274,19 @@
|
||||
* @todo stability experimental
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.interaction.DragAndDropOptions
|
||||
* @property {boolean|undefined} fitView Fit view. Default is `true`.
|
||||
* @property {Array.<function(new: ol.format.Format)>|undefined}
|
||||
* formatConstructors Format constructors.
|
||||
* @property {ol.source.Vector|undefined} source Source. If this is defined
|
||||
* then features will be added to this source.
|
||||
* @property {ol.layer.Vector|undefined} layer Layer. If this is defined then
|
||||
* features will be added to this layer's source. If neither `source` nor
|
||||
* `layer` are defined then the dropped features will be added as a new
|
||||
* layer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.interaction.DragPanOptions
|
||||
* @property {ol.Kinetic|undefined} kinetic Kinetic inertia to apply to the pan.
|
||||
@@ -530,6 +549,19 @@
|
||||
* @property {Object|undefined} params Additional parameters.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.source.KMLOptions
|
||||
* @property {Array.<ol.Attribution>|undefined} attributions Attributions.
|
||||
* @property {Document|undefined} doc Document.
|
||||
* @property {ol.Extent|undefined} extent Extent.
|
||||
* @property {string|undefined} logo Logo.
|
||||
* @property {Node|undefined| node Node.
|
||||
* @property {ol.proj.ProjectionLike} projection Projection.
|
||||
* @property {ol.proj.ProjectionLike} reprojectTo Re-project to.
|
||||
* @property {string|undefined} text Text.
|
||||
* @property {string|undefined} url URL.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} olx.source.MapQuestOptions
|
||||
* @property {ol.TileLoadFunctionType|undefined} tileLoadFunction Optional
|
||||
|
||||
@@ -23,6 +23,12 @@ ol.format.Format = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<string>} Extensions.
|
||||
*/
|
||||
ol.format.Format.prototype.getExtensions = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.format.FormatType} Format.
|
||||
*/
|
||||
|
||||
@@ -41,6 +41,13 @@ ol.format.GeoJSON = function(opt_options) {
|
||||
goog.inherits(ol.format.GeoJSON, ol.format.JSON);
|
||||
|
||||
|
||||
/**
|
||||
* @const {Array.<string>}
|
||||
* @private
|
||||
*/
|
||||
ol.format.GeoJSON.EXTENSIONS_ = ['.geojson'];
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONObject} object Object.
|
||||
* @private
|
||||
@@ -278,6 +285,14 @@ ol.format.GeoJSON.GEOMETRY_WRITERS_ = {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.GeoJSON.prototype.getExtensions = function() {
|
||||
return ol.format.GeoJSON.EXTENSIONS_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
1
src/ol/format/kmlformat.exports
Normal file
1
src/ol/format/kmlformat.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.format.KML
|
||||
1409
src/ol/format/kmlformat.js
Normal file
1409
src/ol/format/kmlformat.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
goog.provide('ol.format.XML');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom.NodeType');
|
||||
goog.require('goog.dom.xml');
|
||||
goog.require('ol.format.Format');
|
||||
goog.require('ol.format.FormatType');
|
||||
@@ -17,57 +19,6 @@ ol.format.XML = function() {
|
||||
goog.inherits(ol.format.XML, ol.format.Format);
|
||||
|
||||
|
||||
/**
|
||||
* @param {Document|Node|Object|string} source Source.
|
||||
* @private
|
||||
* @return {Document} Document.
|
||||
*/
|
||||
ol.format.XML.prototype.getDocument_ = function(source) {
|
||||
if (source instanceof Document) {
|
||||
return source;
|
||||
} else if (goog.isString(source)) {
|
||||
return goog.dom.xml.loadXml(source);
|
||||
} else {
|
||||
goog.asserts.fail();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Document|Node|Object|string} source Source.
|
||||
* @private
|
||||
* @return {Document|Node} Document.
|
||||
*/
|
||||
ol.format.XML.prototype.getDocumentOrNode_ = function(source) {
|
||||
if (source instanceof Document) {
|
||||
return source;
|
||||
} else if (source instanceof Node) {
|
||||
return source;
|
||||
} else if (goog.isString(source)) {
|
||||
return goog.dom.xml.loadXml(source);
|
||||
} else {
|
||||
goog.asserts.fail();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Document|Node|Object|string} source Source.
|
||||
* @private
|
||||
* @return {Node} Node.
|
||||
*/
|
||||
ol.format.XML.prototype.getNode_ = function(source) {
|
||||
if (source instanceof Node) {
|
||||
return source;
|
||||
} else {
|
||||
goog.asserts.fail();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -80,7 +31,31 @@ ol.format.XML.prototype.getType = function() {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.XML.prototype.readFeature = function(source) {
|
||||
return this.readFeatureFromNode(this.getNode_(source));
|
||||
if (source instanceof Document) {
|
||||
return this.readFeatureFromDocument(source);
|
||||
} else if (source instanceof Node) {
|
||||
return this.readFeatureFromNode(source);
|
||||
} else if (goog.isString(source)) {
|
||||
var doc = goog.dom.xml.loadXml(source);
|
||||
return this.readFeatureFromDocument(doc);
|
||||
} else {
|
||||
goog.asserts.fail();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Document} doc Document.
|
||||
* @return {ol.Feature} Feature.
|
||||
*/
|
||||
ol.format.XML.prototype.readFeatureFromDocument = function(doc) {
|
||||
var features = this.readFeaturesFromDocument(doc);
|
||||
if (features.length > 0) {
|
||||
return features[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -95,11 +70,13 @@ ol.format.XML.prototype.readFeatureFromNode = goog.abstractMethod;
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.XML.prototype.readFeatures = function(source) {
|
||||
var documentOrNode = this.getDocumentOrNode_(source);
|
||||
if (documentOrNode instanceof Document) {
|
||||
return this.readFeaturesFromDocument(documentOrNode);
|
||||
} else if (documentOrNode instanceof Node) {
|
||||
return this.readFeaturesFromNode(documentOrNode);
|
||||
if (source instanceof Document) {
|
||||
return this.readFeaturesFromDocument(source);
|
||||
} else if (source instanceof Node) {
|
||||
return this.readFeaturesFromNode(source);
|
||||
} else if (goog.isString(source)) {
|
||||
var doc = goog.dom.xml.loadXml(source);
|
||||
return this.readFeaturesFromDocument(doc);
|
||||
} else {
|
||||
goog.asserts.fail();
|
||||
return null;
|
||||
@@ -113,8 +90,15 @@ ol.format.XML.prototype.readFeatures = function(source) {
|
||||
* @return {Array.<ol.Feature>} Features.
|
||||
*/
|
||||
ol.format.XML.prototype.readFeaturesFromDocument = function(doc) {
|
||||
goog.asserts.assert(doc.childNodes.length == 1);
|
||||
return this.readFeaturesFromNode(doc.firstChild);
|
||||
/** @type {Array.<ol.Feature>} */
|
||||
var features = [];
|
||||
var n;
|
||||
for (n = doc.firstChild; !goog.isNull(n); n = n.nextSibling) {
|
||||
if (n.nodeType == goog.dom.NodeType.ELEMENT) {
|
||||
goog.array.extend(features, this.readFeaturesFromNode(n));
|
||||
}
|
||||
}
|
||||
return features;
|
||||
};
|
||||
|
||||
|
||||
@@ -130,10 +114,28 @@ ol.format.XML.prototype.readFeaturesFromNode = goog.abstractMethod;
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.XML.prototype.readGeometry = function(source) {
|
||||
return this.readGeometryFromNode(this.getNode_(source));
|
||||
if (source instanceof Document) {
|
||||
return this.readGeometryFromDocument(source);
|
||||
} else if (source instanceof Node) {
|
||||
return this.readGeometryFromNode(source);
|
||||
} else if (goog.isString(source)) {
|
||||
var doc = goog.dom.xml.loadXml(source);
|
||||
return this.readGeometryFromDocument(doc);
|
||||
} else {
|
||||
goog.asserts.fail();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Document} doc Document.
|
||||
* @protected
|
||||
* @return {ol.geom.Geometry} Geometry.
|
||||
*/
|
||||
ol.format.XML.prototype.readGeometryFromDocument = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @protected
|
||||
@@ -146,10 +148,28 @@ ol.format.XML.prototype.readGeometryFromNode = goog.abstractMethod;
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.format.XML.prototype.readProjection = function(source) {
|
||||
return this.readProjectionFromNode(this.getNode_(source));
|
||||
if (source instanceof Document) {
|
||||
return this.readProjectionFromDocument(source);
|
||||
} else if (source instanceof Node) {
|
||||
return this.readProjectionFromNode(source);
|
||||
} else if (goog.isString(source)) {
|
||||
var doc = goog.dom.xml.loadXml(source);
|
||||
return this.readProjectionFromDocument(doc);
|
||||
} else {
|
||||
goog.asserts.fail();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Document} doc Document.
|
||||
* @protected
|
||||
* @return {ol.proj.Projection} Projection.
|
||||
*/
|
||||
ol.format.XML.prototype.readProjectionFromDocument = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @protected
|
||||
|
||||
1
src/ol/interaction/draganddropinteraction.exports
Normal file
1
src/ol/interaction/draganddropinteraction.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.interaction.DragAndDrop
|
||||
202
src/ol/interaction/draganddropinteraction.js
Normal file
202
src/ol/interaction/draganddropinteraction.js
Normal file
@@ -0,0 +1,202 @@
|
||||
// FIXME should handle all geo-referenced data, not just vector data
|
||||
|
||||
goog.provide('ol.interaction.DragAndDrop');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.FileDropHandler');
|
||||
goog.require('goog.events.FileDropHandler.EventType');
|
||||
goog.require('goog.fs.FileReader');
|
||||
goog.require('goog.functions');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.Vector');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.interaction.Interaction}
|
||||
* @param {olx.interaction.DragAndDropOptions=} opt_options Options.
|
||||
*/
|
||||
ol.interaction.DragAndDrop = function(opt_options) {
|
||||
|
||||
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.fitView_ = goog.isDef(options.fitView) ? options.fitView : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<function(new: ol.format.Format)>}
|
||||
*/
|
||||
this.formatConstructors_ = goog.isDef(options.formatConstructors) ?
|
||||
options.formatConstructors : [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.source.Vector}
|
||||
*/
|
||||
this.source_ = goog.isDef(options.source) ? options.source : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.layer.Vector}
|
||||
*/
|
||||
this.layer_ = goog.isDef(options.layer) ? options.layer : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.events.FileDropHandler}
|
||||
*/
|
||||
this.fileDropHandler_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.events.Key|undefined}
|
||||
*/
|
||||
this.dropListenKey_ = undefined;
|
||||
|
||||
};
|
||||
goog.inherits(ol.interaction.DragAndDrop, ol.interaction.Interaction);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.disposeInternal = function() {
|
||||
if (goog.isDef(this.dropListenKey_)) {
|
||||
goog.events.unlistenByKey(this.dropListenKey_);
|
||||
}
|
||||
goog.base(this, 'disposeInternal');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.BrowserEvent} event Event.
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.handleDrop_ = function(event) {
|
||||
var files = event.getBrowserEvent().dataTransfer.files;
|
||||
var i, ii;
|
||||
for (i = 0, ii = files.length; i < ii; ++i) {
|
||||
var reader = goog.fs.FileReader.readAsText(files[i]);
|
||||
reader.addCallback(this.handleResult_, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} result Result.
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.handleResult_ = function(result) {
|
||||
var map = this.getMap();
|
||||
goog.asserts.assert(!goog.isNull(map));
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(goog.isDef(view));
|
||||
var view2D = view.getView2D();
|
||||
var targetProjection;
|
||||
if (!goog.isNull(this.source_)) {
|
||||
targetProjection = this.source_.getProjection();
|
||||
} else if (!goog.isNull(this.layer_)) {
|
||||
targetProjection = this.layer_.getSource().getProjection();
|
||||
} else {
|
||||
targetProjection = view2D.getProjection();
|
||||
}
|
||||
var formatConstructors = this.formatConstructors_;
|
||||
var features = [];
|
||||
var i, ii;
|
||||
for (i = 0, ii = formatConstructors.length; i < ii; ++i) {
|
||||
var formatConstructor = formatConstructors[i];
|
||||
var format = new formatConstructor();
|
||||
var readFeatures = this.tryReadFeatures_(format, result);
|
||||
if (!goog.isNull(readFeatures)) {
|
||||
var featureProjection = format.readProjection(result);
|
||||
var transform = ol.proj.getTransform(featureProjection, targetProjection);
|
||||
var j, jj;
|
||||
for (j = 0, jj = readFeatures.length; j < jj; ++j) {
|
||||
var feature = readFeatures[j];
|
||||
var geometry = feature.getGeometry();
|
||||
if (!goog.isNull(geometry)) {
|
||||
geometry.transform(transform);
|
||||
}
|
||||
features.push(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (features.length > 0) {
|
||||
var source;
|
||||
if (!goog.isNull(this.source_)) {
|
||||
source = this.source_;
|
||||
} else if (!goog.isNull(this.layer_)) {
|
||||
source = this.layer_.getSource();
|
||||
goog.asserts.assertInstanceof(source, ol.source.Vector);
|
||||
} else {
|
||||
source = new ol.source.Vector();
|
||||
}
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
source.addFeature(features[i]);
|
||||
}
|
||||
if (goog.isNull(this.layer_)) {
|
||||
map.getLayers().push(new ol.layer.Vector({
|
||||
source: source
|
||||
}));
|
||||
}
|
||||
if (this.fitView_) {
|
||||
view2D.fitExtent(source.getExtent(), map.getSize());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.handleMapBrowserEvent =
|
||||
goog.functions.TRUE;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.setMap = function(map) {
|
||||
if (goog.isDef(this.dropListenKey_)) {
|
||||
goog.events.unlistenByKey(this.dropListenKey_);
|
||||
this.dropListenKey_ = undefined;
|
||||
}
|
||||
if (!goog.isNull(this.fileDropHandler_)) {
|
||||
goog.dispose(this.fileDropHandler_);
|
||||
this.fileDropHandler_ = null;
|
||||
}
|
||||
goog.asserts.assert(!goog.isDef(this.dropListenKey_));
|
||||
goog.base(this, 'setMap', map);
|
||||
if (!goog.isNull(map)) {
|
||||
this.fileDropHandler_ = new goog.events.FileDropHandler(map.getViewport());
|
||||
this.dropListenKey_ = goog.events.listen(
|
||||
this.fileDropHandler_, goog.events.FileDropHandler.EventType.DROP,
|
||||
this.handleDrop_, false, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.format.Format} format Format.
|
||||
* @param {string} text Text.
|
||||
* @private
|
||||
* @return {Array.<ol.Feature>} Features.
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.tryReadFeatures_ = function(format, text) {
|
||||
try {
|
||||
return format.readFeatures(text);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
1
src/ol/source/kmlsource.exports
Normal file
1
src/ol/source/kmlsource.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.source.KML
|
||||
31
src/ol/source/kmlsource.js
Normal file
31
src/ol/source/kmlsource.js
Normal file
@@ -0,0 +1,31 @@
|
||||
goog.provide('ol.source.KML');
|
||||
|
||||
goog.require('ol.format.KML');
|
||||
goog.require('ol.source.VectorFile');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.VectorFile}
|
||||
* @param {olx.source.KMLOptions=} opt_options Options.
|
||||
*/
|
||||
ol.source.KML = function(opt_options) {
|
||||
|
||||
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
doc: options.doc,
|
||||
extent: options.extent,
|
||||
format: new ol.format.KML(),
|
||||
logo: options.logo,
|
||||
node: options.node,
|
||||
projection: options.projection,
|
||||
reprojectTo: options.reprojectTo,
|
||||
text: options.text,
|
||||
url: options.url
|
||||
});
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.KML, ol.source.VectorFile);
|
||||
202
src/ol/xml.js
Normal file
202
src/ol/xml.js
Normal file
@@ -0,0 +1,202 @@
|
||||
goog.provide('ol.xml');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom.NodeType');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {function(Node, Array.<*>)}
|
||||
*/
|
||||
ol.xml.Parser;
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {boolean} normalizeWhitespace Normalize whitespace.
|
||||
* @return {string} All text content.
|
||||
*/
|
||||
ol.xml.getAllTextContent = function(node, normalizeWhitespace) {
|
||||
return ol.xml.getAllTextContent_(node, normalizeWhitespace, []).join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {boolean} normalizeWhitespace Normalize whitespace.
|
||||
* @param {Array.<String|string>} accumulator Accumulator.
|
||||
* @private
|
||||
* @return {Array.<String|string>} Accumulator.
|
||||
*/
|
||||
ol.xml.getAllTextContent_ = function(node, normalizeWhitespace, accumulator) {
|
||||
if (node.nodeType == goog.dom.NodeType.CDATA_SECTION ||
|
||||
node.nodeType == goog.dom.NodeType.TEXT) {
|
||||
if (normalizeWhitespace) {
|
||||
// FIXME understand why goog.dom.getTextContent_ uses String here
|
||||
accumulator.push(String(node.nodeValue).replace(/(\r\n|\r|\n)/g, ''));
|
||||
} else {
|
||||
accumulator.push(node.nodeValue);
|
||||
}
|
||||
} else {
|
||||
var n;
|
||||
for (n = node.firstChild; !goog.isNull(n); n = n.nextSibling) {
|
||||
ol.xml.getAllTextContent_(n, normalizeWhitespace, accumulator);
|
||||
}
|
||||
}
|
||||
return accumulator;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function(this: T, Node, Array.<*>): (Array.<*>|undefined)}
|
||||
* valueReader Value reader.
|
||||
* @param {T=} opt_obj Scope.
|
||||
* @return {ol.xml.Parser} Parser.
|
||||
* @template T
|
||||
*/
|
||||
ol.xml.makeArrayExtender = function(valueReader, opt_obj) {
|
||||
return (
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {Array.<*>} objectStack Object stack.
|
||||
*/
|
||||
function(node, objectStack) {
|
||||
var value = valueReader.call(opt_obj, node, objectStack);
|
||||
if (goog.isDef(value)) {
|
||||
goog.asserts.assert(goog.isArray(value));
|
||||
var array = /** @type {Array.<*>} */
|
||||
(objectStack[objectStack.length - 1]);
|
||||
goog.asserts.assert(goog.isArray(array));
|
||||
goog.array.extend(array, value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
|
||||
* @param {T=} opt_obj Scope.
|
||||
* @return {ol.xml.Parser} Parser.
|
||||
* @template T
|
||||
*/
|
||||
ol.xml.makeArrayPusher = function(valueReader, opt_obj) {
|
||||
return (
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {Array.<*>} objectStack Object stack.
|
||||
*/
|
||||
function(node, objectStack) {
|
||||
var value = valueReader.call(opt_obj, node, objectStack);
|
||||
if (goog.isDef(value)) {
|
||||
var array = objectStack[objectStack.length - 1];
|
||||
goog.asserts.assert(goog.isArray(array));
|
||||
array.push(value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
|
||||
* @param {T=} opt_obj Scope.
|
||||
* @return {ol.xml.Parser} Parser.
|
||||
* @template T
|
||||
*/
|
||||
ol.xml.makeReplacer = function(valueReader, opt_obj) {
|
||||
return (
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {Array.<*>} objectStack Object stack.
|
||||
*/
|
||||
function(node, objectStack) {
|
||||
var value = valueReader.call(opt_obj, node, objectStack);
|
||||
if (goog.isDef(value)) {
|
||||
objectStack[objectStack.length - 1] = value;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
|
||||
* @param {string=} opt_property Property.
|
||||
* @param {T=} opt_obj Scope.
|
||||
* @return {ol.xml.Parser} Parser.
|
||||
* @template T
|
||||
*/
|
||||
ol.xml.makeObjectPropertySetter = function(valueReader, opt_property, opt_obj) {
|
||||
goog.asserts.assert(goog.isDef(valueReader));
|
||||
return (
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {Array.<*>} objectStack Object stack.
|
||||
*/
|
||||
function(node, objectStack) {
|
||||
var value = valueReader.call(opt_obj, node, objectStack);
|
||||
if (goog.isDef(value)) {
|
||||
var object = /** @type {Object} */
|
||||
(objectStack[objectStack.length - 1]);
|
||||
var property = goog.isDef(opt_property) ?
|
||||
opt_property : node.localName;
|
||||
goog.asserts.assert(goog.isObject(object));
|
||||
goog.object.set(object, property, value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<string>} namespaceURIs Namespace URIs.
|
||||
* @param {Object.<string, ol.xml.Parser>} parsers Parsers.
|
||||
* @return {Object.<string, Object.<string, ol.xml.Parser>>} Parsers NS.
|
||||
*/
|
||||
ol.xml.makeParsersNS = function(namespaceURIs, parsers) {
|
||||
/** @type {Object.<string, Object.<string, ol.xml.Parser>>} */
|
||||
var parsersNS = {};
|
||||
var i, ii;
|
||||
for (i = 0, ii = namespaceURIs.length; i < ii; ++i) {
|
||||
parsersNS[namespaceURIs[i]] = parsers;
|
||||
}
|
||||
return parsersNS;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object.<string, Object.<string, ol.xml.Parser>>} parsersNS
|
||||
* Parsers by namespace.
|
||||
* @param {Node} node Node.
|
||||
* @param {Array.<*>} objectStack Object stack.
|
||||
* @param {*=} opt_obj Scope.
|
||||
*/
|
||||
ol.xml.parse = function(parsersNS, node, objectStack, opt_obj) {
|
||||
var n;
|
||||
for (n = node.firstChild; !goog.isNull(n); n = n.nextSibling) {
|
||||
if (n.nodeType == goog.dom.NodeType.ELEMENT) {
|
||||
var parsers = parsersNS[n.namespaceURI];
|
||||
if (goog.isDef(parsers)) {
|
||||
var parser = parsers[n.localName];
|
||||
if (goog.isDef(parser)) {
|
||||
parser.call(opt_obj, n, objectStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {T} object Object.
|
||||
* @param {Object.<string, Object.<string, ol.xml.Parser>>} parsersNS
|
||||
* Parsers by namespace.
|
||||
* @param {Node} node Node.
|
||||
* @param {Array.<*>} objectStack Object stack.
|
||||
* @param {*=} opt_obj Scope.
|
||||
* @return {T|undefined} Object.
|
||||
* @template T
|
||||
*/
|
||||
ol.xml.pushAndParse = function(object, parsersNS, node, objectStack, opt_obj) {
|
||||
objectStack.push(object);
|
||||
ol.xml.parse(parsersNS, node, objectStack, opt_obj);
|
||||
return objectStack.pop();
|
||||
};
|
||||
4661
test/spec/ol/format/kml/states.kml
Normal file
4661
test/spec/ol/format/kml/states.kml
Normal file
File diff suppressed because one or more lines are too long
1370
test/spec/ol/format/kmlformat.test.js
Normal file
1370
test/spec/ol/format/kmlformat.test.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user