Added KML plugin
This commit is contained in:
parent
e504ee24ae
commit
ca8c8bb806
336
external/KML.js
vendored
Executable file
336
external/KML.js
vendored
Executable file
@ -0,0 +1,336 @@
|
||||
/*global L: true */
|
||||
|
||||
L.KML = L.FeatureGroup.extend({
|
||||
options: {
|
||||
async: true
|
||||
},
|
||||
|
||||
initialize: function(kml, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._kml = kml;
|
||||
this._layers = {};
|
||||
|
||||
if (kml) {
|
||||
this.addKML(kml, options, this.options.async);
|
||||
}
|
||||
},
|
||||
|
||||
loadXML: function(url, cb, options, async) {
|
||||
if (async == undefined) async = this.options.async;
|
||||
if (options == undefined) options = this.options;
|
||||
|
||||
var req = new window.XMLHttpRequest();
|
||||
req.open('GET', url, async);
|
||||
try {
|
||||
req.overrideMimeType('text/xml'); // unsupported by IE
|
||||
} catch(e) {}
|
||||
req.onreadystatechange = function() {
|
||||
if (req.readyState != 4) return;
|
||||
if(req.status == 200) cb(req.responseXML, options);
|
||||
};
|
||||
req.send(null);
|
||||
},
|
||||
|
||||
addKML: function(url, options, async) {
|
||||
var _this = this;
|
||||
var cb = function(gpx, options) { _this._addKML(gpx, options) };
|
||||
this.loadXML(url, cb, options, async);
|
||||
},
|
||||
|
||||
_addKML: function(xml, options) {
|
||||
var layers = L.KML.parseKML(xml);
|
||||
if (!layers || !layers.length) return;
|
||||
for (var i = 0; i < layers.length; i++)
|
||||
{
|
||||
this.fire('addlayer', {
|
||||
layer: layers[i]
|
||||
});
|
||||
this.addLayer(layers[i]);
|
||||
}
|
||||
this.latLngs = L.KML.getLatLngs(xml);
|
||||
this.fire("loaded");
|
||||
},
|
||||
|
||||
latLngs: []
|
||||
});
|
||||
|
||||
L.Util.extend(L.KML, {
|
||||
|
||||
parseKML: function (xml) {
|
||||
var style = this.parseStyle(xml);
|
||||
var el = xml.getElementsByTagName("Folder");
|
||||
var layers = [], l;
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
if (!this._check_folder(el[i])) { continue; }
|
||||
l = this.parseFolder(el[i], style);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
el = xml.getElementsByTagName('Placemark');
|
||||
for (var j = 0; j < el.length; j++) {
|
||||
if (!this._check_folder(el[j])) { continue; }
|
||||
l = this.parsePlacemark(el[j], xml, style);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
return layers;
|
||||
},
|
||||
|
||||
// Return false if e's first parent Folder is not [folder]
|
||||
// - returns true if no parent Folders
|
||||
_check_folder: function (e, folder) {
|
||||
e = e.parentElement;
|
||||
while (e && e.tagName !== "Folder")
|
||||
{
|
||||
e = e.parentElement;
|
||||
}
|
||||
return !e || e === folder;
|
||||
},
|
||||
|
||||
parseStyle: function (xml) {
|
||||
var style = {};
|
||||
var sl = xml.getElementsByTagName("Style");
|
||||
|
||||
//for (var i = 0; i < sl.length; i++) {
|
||||
var attributes = {color: true, width: true, Icon: true, href: true,
|
||||
hotSpot: true};
|
||||
|
||||
function _parse(xml) {
|
||||
var options = {};
|
||||
for (var i = 0; i < xml.childNodes.length; i++) {
|
||||
var e = xml.childNodes[i];
|
||||
var key = e.tagName;
|
||||
if (!attributes[key]) { continue; }
|
||||
if (key === 'hotSpot')
|
||||
{
|
||||
for (var j = 0; j < e.attributes.length; j++) {
|
||||
options[e.attributes[j].name] = e.attributes[j].nodeValue;
|
||||
}
|
||||
} else {
|
||||
var value = e.childNodes[0].nodeValue;
|
||||
if (key === 'color') {
|
||||
options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
|
||||
options.color = "#" + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4);
|
||||
} else if (key === 'width') {
|
||||
options.weight = value;
|
||||
} else if (key === 'Icon') {
|
||||
ioptions = _parse(e);
|
||||
if (ioptions.href) { options.href = ioptions.href; }
|
||||
} else if (key === 'href') {
|
||||
options.href = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
for (var i = 0; i < sl.length; i++) {
|
||||
var e = sl[i], el;
|
||||
var options = {}, poptions = {}, ioptions = {};
|
||||
el = e.getElementsByTagName("LineStyle");
|
||||
if (el && el[0]) { options = _parse(el[0]); }
|
||||
el = e.getElementsByTagName("PolyStyle");
|
||||
if (el && el[0]) { poptions = _parse(el[0]); }
|
||||
if (poptions.color) { options.fillColor = poptions.color; }
|
||||
if (poptions.opacity) { options.fillOpacity = poptions.opacity; }
|
||||
el = e.getElementsByTagName("IconStyle");
|
||||
if (el && el[0]) { ioptions = _parse(el[0]); }
|
||||
if (ioptions.href) {
|
||||
// save anchor info until the image is loaded
|
||||
options.icon = new L.KMLIcon({
|
||||
iconUrl: ioptions.href,
|
||||
shadowUrl: null,
|
||||
iconAnchorRef: {x: ioptions.x, y: ioptions.y},
|
||||
iconAnchorType: {x: ioptions.xunits, y: ioptions.yunits}
|
||||
});
|
||||
}
|
||||
style['#' + e.getAttribute('id')] = options;
|
||||
}
|
||||
return style;
|
||||
},
|
||||
|
||||
parseFolder: function (xml, style) {
|
||||
var el, layers = [], l;
|
||||
el = xml.getElementsByTagName('Folder');
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
if (!this._check_folder(el[i], xml)) { continue; }
|
||||
l = this.parseFolder(el[i], style);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
el = xml.getElementsByTagName('Placemark');
|
||||
for (var j = 0; j < el.length; j++) {
|
||||
if (!this._check_folder(el[j], xml)) { continue; }
|
||||
l = this.parsePlacemark(el[j], xml, style);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
if (!layers.length) { return; }
|
||||
if (layers.length === 1) { return layers[0]; }
|
||||
return new L.FeatureGroup(layers);
|
||||
},
|
||||
|
||||
parsePlacemark: function (place, xml, style) {
|
||||
var i, j, el, options = {};
|
||||
el = place.getElementsByTagName('styleUrl');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var url = el[i].childNodes[0].nodeValue;
|
||||
for (var a in style[url])
|
||||
{
|
||||
// for jshint
|
||||
if (true)
|
||||
{
|
||||
options[a] = style[url][a];
|
||||
}
|
||||
}
|
||||
}
|
||||
var layers = [];
|
||||
|
||||
var parse = ['LineString', 'Polygon', 'Point'];
|
||||
for (j in parse) {
|
||||
// for jshint
|
||||
if (true)
|
||||
{
|
||||
var tag = parse[j];
|
||||
el = place.getElementsByTagName(tag);
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var l = this["parse" + tag](el[i], xml, options);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!layers.length) {
|
||||
return;
|
||||
}
|
||||
var layer = layers[0];
|
||||
if (layers.length > 1) {
|
||||
layer = new L.FeatureGroup(layers);
|
||||
}
|
||||
|
||||
var name, descr = "";
|
||||
el = place.getElementsByTagName('name');
|
||||
if (el.length) {
|
||||
name = el[0].childNodes[0].nodeValue;
|
||||
}
|
||||
el = place.getElementsByTagName('description');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
for (j = 0; j < el[i].childNodes.length; j++) {
|
||||
descr = descr + el[i].childNodes[j].nodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (name) {
|
||||
layer.bindPopup("<h2>" + name + "</h2>" + descr);
|
||||
}
|
||||
|
||||
return layer;
|
||||
},
|
||||
|
||||
parseCoords: function (xml) {
|
||||
var el = xml.getElementsByTagName('coordinates');
|
||||
return this._read_coords(el[0]);
|
||||
},
|
||||
|
||||
parseLineString: function (line, xml, options) {
|
||||
var coords = this.parseCoords(line);
|
||||
if (!coords.length) { return; }
|
||||
return new L.Polyline(coords, options);
|
||||
},
|
||||
|
||||
parsePoint: function (line, xml, options) {
|
||||
var el = line.getElementsByTagName('coordinates');
|
||||
if (!el.length) {
|
||||
return;
|
||||
}
|
||||
var ll = el[0].childNodes[0].nodeValue.split(',');
|
||||
return new L.KMLMarker(new L.LatLng(ll[1], ll[0]), options);
|
||||
},
|
||||
|
||||
parsePolygon: function (line, xml, options) {
|
||||
var el, polys = [], inner = [], i, coords;
|
||||
el = line.getElementsByTagName('outerBoundaryIs');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
coords = this.parseCoords(el[i]);
|
||||
if (coords) {
|
||||
polys.push(coords);
|
||||
}
|
||||
}
|
||||
el = line.getElementsByTagName('innerBoundaryIs');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
coords = this.parseCoords(el[i]);
|
||||
if (coords) {
|
||||
inner.push(coords);
|
||||
}
|
||||
}
|
||||
if (!polys.length) {
|
||||
return;
|
||||
}
|
||||
if (options.fillColor) {
|
||||
options.fill = true;
|
||||
}
|
||||
if (polys.length === 1) {
|
||||
return new L.Polygon(polys.concat(inner), options);
|
||||
}
|
||||
return new L.MultiPolygon(polys, options);
|
||||
},
|
||||
|
||||
getLatLngs: function (xml) {
|
||||
var el = xml.getElementsByTagName('coordinates');
|
||||
var coords = [];
|
||||
for (var j = 0; j < el.length; j++) {
|
||||
// text might span many childnodes
|
||||
coords = coords.concat(this._read_coords(el[j]));
|
||||
}
|
||||
return coords;
|
||||
},
|
||||
|
||||
_read_coords: function (el) {
|
||||
var text = "", coords = [], i;
|
||||
for (i = 0; i < el.childNodes.length; i++) {
|
||||
text = text + el.childNodes[i].nodeValue;
|
||||
}
|
||||
text = text.split(/[\s\n]+/);
|
||||
for (i = 0; i < text.length; i++) {
|
||||
var ll = text[i].split(',');
|
||||
if (ll.length < 2) {
|
||||
continue;
|
||||
}
|
||||
coords.push(new L.LatLng(ll[1], ll[0]));
|
||||
}
|
||||
return coords;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
L.KMLIcon = L.Icon.extend({
|
||||
|
||||
createIcon: function () {
|
||||
var img = this._createIcon('icon');
|
||||
img.onload = function () {
|
||||
var i = new Image();
|
||||
i.src = this.src;
|
||||
this.style.width = i.width + 'px';
|
||||
this.style.height = i.height + 'px';
|
||||
|
||||
if (this.anchorType.x === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
|
||||
img.style.marginLeft = (-this.anchor.x * i.width) + 'px';
|
||||
}
|
||||
if (this.anchorType.y === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
|
||||
img.style.marginTop = (-(1 - this.anchor.y) * i.height) + 'px';
|
||||
}
|
||||
this.style.display = "";
|
||||
};
|
||||
return img;
|
||||
},
|
||||
|
||||
_setIconStyles: function (img, name) {
|
||||
L.Icon.prototype._setIconStyles.apply(this, [img, name])
|
||||
// save anchor information to the image
|
||||
img.anchor = this.options.iconAnchorRef;
|
||||
img.anchorType = this.options.iconAnchorType;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
L.KMLMarker = L.Marker.extend({
|
||||
options: {
|
||||
icon: new L.KMLIcon.Default()
|
||||
}
|
||||
});
|
168
external/leaflet.filelayer.js
vendored
Executable file
168
external/leaflet.filelayer.js
vendored
Executable file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Load files *locally* (GeoJSON, KML, GPX) into the map
|
||||
* using the HTML5 File API.
|
||||
*
|
||||
* Requires Pavel Shramov's GPX.js
|
||||
* https://github.com/shramov/leaflet-plugins/blob/d74d67/layer/vector/GPX.js
|
||||
*/
|
||||
var FileLoader = L.Class.extend({
|
||||
includes: L.Mixin.Events,
|
||||
options: {
|
||||
layerOptions: {}
|
||||
},
|
||||
|
||||
initialize: function (map, options) {
|
||||
this._map = map;
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._parsers = {
|
||||
'geojson': this._loadGeoJSON,
|
||||
'gpx': this._convertToGeoJSON,
|
||||
'kml': this._convertToGeoJSON
|
||||
};
|
||||
},
|
||||
|
||||
load: function (file /* File */) {
|
||||
// Check file extension
|
||||
var ext = file.name.split('.').pop(),
|
||||
parser = this._parsers[ext];
|
||||
if (!parser) {
|
||||
window.alert("Unsupported file type " + file.type + '(' + ext + ')');
|
||||
return;
|
||||
}
|
||||
// Read selected file using HTML5 File API
|
||||
var reader = new FileReader();
|
||||
reader.onload = L.Util.bind(function (e) {
|
||||
this.fire('data:loading', {filename: file.name, format: ext});
|
||||
var layer = parser.call(this, e.target.result, ext);
|
||||
this.fire('data:loaded', {layer: layer, filename: file.name, format: ext});
|
||||
}, this);
|
||||
reader.readAsText(file);
|
||||
},
|
||||
|
||||
_loadGeoJSON: function (content) {
|
||||
if (typeof content == 'string') {
|
||||
content = JSON.parse(content);
|
||||
}
|
||||
return L.geoJson(content, this.options.layerOptions).addTo(this._map);
|
||||
},
|
||||
|
||||
_convertToGeoJSON: function (content, format) {
|
||||
// Format is either 'gpx' or 'kml'
|
||||
if (typeof content == 'string') {
|
||||
content = ( new window.DOMParser() ).parseFromString(content, "text/xml");
|
||||
}
|
||||
var geojson = toGeoJSON[format](content);
|
||||
return this._loadGeoJSON(geojson);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
L.Control.FileLayerLoad = L.Control.extend({
|
||||
statics: {
|
||||
TITLE: 'Load local file (GPX, KML, GeoJSON)',
|
||||
LABEL: '⌅'
|
||||
},
|
||||
options: {
|
||||
position: 'topleft',
|
||||
fitBounds: true,
|
||||
layerOptions: {}
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this.loader = null;
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this.loader = new FileLoader(map, {layerOptions: this.options.layerOptions});
|
||||
|
||||
this.loader.on('data:loaded', function (e) {
|
||||
// Fit bounds after loading
|
||||
if (this.options.fitBounds) {
|
||||
window.setTimeout(function () {
|
||||
map.fitBounds(e.layer.getBounds()).zoomOut();
|
||||
}, 500);
|
||||
}
|
||||
}, this);
|
||||
|
||||
// Initialize Drag-and-drop
|
||||
this._initDragAndDrop(map);
|
||||
|
||||
// Initialize map control
|
||||
return this._initContainer();
|
||||
},
|
||||
|
||||
_initDragAndDrop: function (map) {
|
||||
var fileLoader = this.loader,
|
||||
dropbox = map._container;
|
||||
|
||||
var callbacks = {
|
||||
dragenter: function () {
|
||||
map.scrollWheelZoom.disable();
|
||||
},
|
||||
dragleave: function () {
|
||||
map.scrollWheelZoom.enable();
|
||||
},
|
||||
dragover: function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
drop: function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var files = Array.prototype.slice.apply(e.dataTransfer.files),
|
||||
i = files.length;
|
||||
setTimeout(function(){
|
||||
fileLoader.load(files.shift());
|
||||
if (files.length > 0) {
|
||||
setTimeout(arguments.callee, 25);
|
||||
}
|
||||
}, 25);
|
||||
map.scrollWheelZoom.enable();
|
||||
}
|
||||
};
|
||||
for (var name in callbacks)
|
||||
dropbox.addEventListener(name, callbacks[name], false);
|
||||
},
|
||||
|
||||
_initContainer: function () {
|
||||
// Create an invisible file input
|
||||
var fileInput = L.DomUtil.create('input', 'hidden', container);
|
||||
fileInput.type = 'file';
|
||||
fileInput.accept = '.gpx,.kml,.geojson';
|
||||
fileInput.style.display = 'none';
|
||||
// Load on file change
|
||||
var fileLoader = this.loader;
|
||||
fileInput.addEventListener("change", function (e) {
|
||||
fileLoader.load(this.files[0]);
|
||||
}, false);
|
||||
|
||||
// Create a button, and bind click on hidden file input
|
||||
var zoomName = 'leaflet-control-filelayer leaflet-control-zoom',
|
||||
barName = 'leaflet-bar',
|
||||
partName = barName + '-part',
|
||||
container = L.DomUtil.create('div', zoomName + ' ' + barName);
|
||||
var link = L.DomUtil.create('a', zoomName + '-in ' + partName, container);
|
||||
link.innerHTML = L.Control.FileLayerLoad.LABEL;
|
||||
link.href = '#';
|
||||
link.title = L.Control.FileLayerLoad.TITLE;
|
||||
|
||||
var stop = L.DomEvent.stopPropagation;
|
||||
L.DomEvent
|
||||
.on(link, 'click', stop)
|
||||
.on(link, 'mousedown', stop)
|
||||
.on(link, 'dblclick', stop)
|
||||
.on(link, 'click', L.DomEvent.preventDefault)
|
||||
.on(link, 'click', function (e) {
|
||||
fileInput.click();
|
||||
e.preventDefault();
|
||||
});
|
||||
return container;
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.fileLayerLoad = function (options) {
|
||||
return new L.Control.FileLayerLoad(options);
|
||||
};
|
224
external/togeojson.js
vendored
Executable file
224
external/togeojson.js
vendored
Executable file
@ -0,0 +1,224 @@
|
||||
toGeoJSON = (function() {
|
||||
'use strict';
|
||||
|
||||
var removeSpace = (/\s*/g),
|
||||
trimSpace = (/^\s*|\s*$/g),
|
||||
splitSpace = (/\s+/);
|
||||
// generate a short, numeric hash of a string
|
||||
function okhash(x) {
|
||||
if (!x || !x.length) return 0;
|
||||
for (var i = 0, h = 0; i < x.length; i++) {
|
||||
h = ((h << 5) - h) + x.charCodeAt(i) | 0;
|
||||
} return h;
|
||||
}
|
||||
// all Y children of X
|
||||
function get(x, y) { return x.getElementsByTagName(y); }
|
||||
function attr(x, y) { return x.getAttribute(y); }
|
||||
function attrf(x, y) { return parseFloat(attr(x, y)); }
|
||||
// one Y child of X, if any, otherwise null
|
||||
function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
|
||||
function norm(el) { if (el.normalize) { el.normalize(); } return el; }
|
||||
// cast array x into numbers
|
||||
function numarray(x) {
|
||||
for (var j = 0, o = []; j < x.length; j++) o[j] = parseFloat(x[j]);
|
||||
return o;
|
||||
}
|
||||
function clean(x) {
|
||||
var o = {};
|
||||
for (var i in x) if (x[i]) o[i] = x[i];
|
||||
return o;
|
||||
}
|
||||
// get the content of a text node, if any
|
||||
function nodeVal(x) { if (x) {norm(x);} return x && x.firstChild && x.firstChild.nodeValue; }
|
||||
// get one coordinate from a coordinate array, if any
|
||||
function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
|
||||
// get all coordinates from a coordinate array as [[],[]]
|
||||
function coord(v) {
|
||||
var coords = v.replace(trimSpace, '').split(splitSpace),
|
||||
o = [];
|
||||
for (var i = 0; i < coords.length; i++) {
|
||||
o.push(coord1(coords[i]));
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function coordPair(x) { return [attrf(x, 'lon'), attrf(x, 'lat')]; }
|
||||
|
||||
// create a new feature collection parent object
|
||||
function fc() {
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
features: []
|
||||
};
|
||||
}
|
||||
|
||||
var serializer;
|
||||
if (typeof XMLSerializer !== 'undefined') {
|
||||
serializer = new XMLSerializer();
|
||||
} else if (typeof require !== 'undefined') {
|
||||
serializer = new (require('xmldom').XMLSerializer)();
|
||||
}
|
||||
function xml2str(str) { return serializer.serializeToString(str); }
|
||||
|
||||
var t = {
|
||||
kml: function(doc, o) {
|
||||
o = o || {};
|
||||
|
||||
var gj = fc(),
|
||||
// styleindex keeps track of hashed styles in order to match features
|
||||
styleIndex = {},
|
||||
// atomic geospatial types supported by KML - MultiGeometry is
|
||||
// handled separately
|
||||
geotypes = ['Polygon', 'LineString', 'Point', 'Track'],
|
||||
// all root placemarks in the file
|
||||
placemarks = get(doc, 'Placemark'),
|
||||
styles = get(doc, 'Style');
|
||||
|
||||
for (var k = 0; k < styles.length; k++) {
|
||||
styleIndex['#' + attr(styles[k], 'id')] = okhash(xml2str(styles[k])).toString(16);
|
||||
}
|
||||
for (var j = 0; j < placemarks.length; j++) {
|
||||
gj.features = gj.features.concat(getPlacemark(placemarks[j]));
|
||||
}
|
||||
function gxCoord(v) { return numarray(v.split(' ')); }
|
||||
function gxCoords(root) {
|
||||
var elems = get(root, 'coord', 'gx'), coords = [];
|
||||
for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
|
||||
return coords;
|
||||
}
|
||||
function getGeometry(root) {
|
||||
var geomNode, geomNodes, i, j, k, geoms = [];
|
||||
if (get1(root, 'MultiGeometry')) return getGeometry(get1(root, 'MultiGeometry'));
|
||||
if (get1(root, 'MultiTrack')) return getGeometry(get1(root, 'MultiTrack'));
|
||||
for (i = 0; i < geotypes.length; i++) {
|
||||
geomNodes = get(root, geotypes[i]);
|
||||
if (geomNodes) {
|
||||
for (j = 0; j < geomNodes.length; j++) {
|
||||
geomNode = geomNodes[j];
|
||||
if (geotypes[i] == 'Point') {
|
||||
geoms.push({
|
||||
type: 'Point',
|
||||
coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
|
||||
});
|
||||
} else if (geotypes[i] == 'LineString') {
|
||||
geoms.push({
|
||||
type: 'LineString',
|
||||
coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
|
||||
});
|
||||
} else if (geotypes[i] == 'Polygon') {
|
||||
var rings = get(geomNode, 'LinearRing'),
|
||||
coords = [];
|
||||
for (k = 0; k < rings.length; k++) {
|
||||
coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
|
||||
}
|
||||
geoms.push({
|
||||
type: 'Polygon',
|
||||
coordinates: coords
|
||||
});
|
||||
} else if (geotypes[i] == 'Track') {
|
||||
geoms.push({
|
||||
type: 'LineString',
|
||||
coordinates: gxCoords(geomNode)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return geoms;
|
||||
}
|
||||
function getPlacemark(root) {
|
||||
var geoms = getGeometry(root), i, properties = {},
|
||||
name = nodeVal(get1(root, 'name')),
|
||||
styleUrl = nodeVal(get1(root, 'styleUrl')),
|
||||
description = nodeVal(get1(root, 'description')),
|
||||
extendedData = get1(root, 'ExtendedData');
|
||||
|
||||
if (!geoms.length) return [];
|
||||
if (name) properties.name = name;
|
||||
if (styleUrl && styleIndex[styleUrl]) {
|
||||
properties.styleUrl = styleUrl;
|
||||
properties.styleHash = styleIndex[styleUrl];
|
||||
}
|
||||
if (description) properties.description = description;
|
||||
if (extendedData) {
|
||||
var datas = get(extendedData, 'Data'),
|
||||
simpleDatas = get(extendedData, 'SimpleData');
|
||||
|
||||
for (i = 0; i < datas.length; i++) {
|
||||
properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
|
||||
}
|
||||
for (i = 0; i < simpleDatas.length; i++) {
|
||||
properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
|
||||
}
|
||||
}
|
||||
return [{
|
||||
type: 'Feature',
|
||||
geometry: (geoms.length === 1) ? geoms[0] : {
|
||||
type: 'GeometryCollection',
|
||||
geometries: geoms
|
||||
},
|
||||
properties: properties
|
||||
}];
|
||||
}
|
||||
return gj;
|
||||
},
|
||||
gpx: function(doc, o) {
|
||||
var i,
|
||||
tracks = get(doc, 'trk'),
|
||||
routes = get(doc, 'rte'),
|
||||
waypoints = get(doc, 'wpt'),
|
||||
// a feature collection
|
||||
gj = fc();
|
||||
for (i = 0; i < tracks.length; i++) {
|
||||
gj.features.push(getLinestring(tracks[i], 'trkpt'));
|
||||
}
|
||||
for (i = 0; i < routes.length; i++) {
|
||||
gj.features.push(getLinestring(routes[i], 'rtept'));
|
||||
}
|
||||
for (i = 0; i < waypoints.length; i++) {
|
||||
gj.features.push(getPoint(waypoints[i]));
|
||||
}
|
||||
function getLinestring(node, pointname) {
|
||||
var j, pts = get(node, pointname), line = [];
|
||||
for (j = 0; j < pts.length; j++) {
|
||||
line.push(coordPair(pts[j]));
|
||||
}
|
||||
return {
|
||||
type: 'Feature',
|
||||
properties: getProperties(node),
|
||||
geometry: {
|
||||
type: 'LineString',
|
||||
coordinates: line
|
||||
}
|
||||
};
|
||||
}
|
||||
function getPoint(node) {
|
||||
var prop = getProperties(node);
|
||||
prop.ele = nodeVal(get1(node, 'ele'));
|
||||
prop.sym = nodeVal(get1(node, 'sym'));
|
||||
return {
|
||||
type: 'Feature',
|
||||
properties: prop,
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: coordPair(node)
|
||||
}
|
||||
};
|
||||
}
|
||||
function getProperties(node) {
|
||||
var meta = ['name', 'desc', 'author', 'copyright', 'link',
|
||||
'time', 'keywords'],
|
||||
prop = {},
|
||||
k;
|
||||
for (k = 0; k < meta.length; k++) {
|
||||
prop[meta[k]] = nodeVal(get1(node, meta[k]));
|
||||
}
|
||||
return clean(prop);
|
||||
}
|
||||
return gj;
|
||||
}
|
||||
};
|
||||
return t;
|
||||
})();
|
||||
|
||||
if (typeof module !== 'undefined') module.exports = toGeoJSON;
|
62
plugins/kml_plugin.user.js
Executable file
62
plugins/kml_plugin.user.js
Executable file
@ -0,0 +1,62 @@
|
||||
// ==UserScript==
|
||||
// @id overlay-kml@danielatkins
|
||||
// @name IITC plugin: overlay KML
|
||||
// @category Info
|
||||
// @version 0.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allows users to overlay their own KML / GPX files on top of IITC
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.overlayKML = function() {};
|
||||
|
||||
window.plugin.overlayKML.loadExternals = function() {
|
||||
try { console.log('Loading leaflet.filelayer JS now'); } catch(e) {}
|
||||
@@INCLUDERAW:external/leaflet.filelayer.js@@
|
||||
try { console.log('done loading leaflet.filelayer JS'); } catch(e) {}
|
||||
|
||||
try { console.log('Loading KML JS now'); } catch(e) {}
|
||||
@@INCLUDERAW:external/KML.js@@
|
||||
try { console.log('done loading KML JS'); } catch(e) {}
|
||||
|
||||
try { console.log('Loading togeojson JS now'); } catch(e) {}
|
||||
@@INCLUDERAW:external/togeojson.js@@
|
||||
try { console.log('done loading togeojson JS'); } catch(e) {}
|
||||
|
||||
window.plugin.overlayKML.load();
|
||||
}
|
||||
|
||||
// window.plugin.overlayKML.setupCallback = function() {
|
||||
// $('#toolbox').append(' <a onclick="window.plugin.overlayKML.load()" title="Load KML to overlay on top of Ingress Intel Map">Overlay KML</a>');
|
||||
// }
|
||||
|
||||
window.plugin.overlayKML.load = function() {
|
||||
// Provide popup window allow user to select KML to overlay
|
||||
L.Control.FileLayerLoad.LABEL = 'O';
|
||||
L.Control.fileLayerLoad({
|
||||
fitBounds: true,
|
||||
layerOptions: {
|
||||
pointToLayer: function (data, latlng) {
|
||||
return L.marker(latlng);
|
||||
}},
|
||||
}).addTo(map);
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.plugin.overlayKML.loadExternals();
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
Loading…
x
Reference in New Issue
Block a user