[Mapbender-commits] r9247 - trunk/mapbender/http/extensions
svn_mapbender at osgeo.org
svn_mapbender at osgeo.org
Mon Jul 13 00:49:34 PDT 2015
Author: armin11
Date: 2015-07-13 00:49:34 -0700 (Mon, 13 Jul 2015)
New Revision: 9247
Modified:
trunk/mapbender/http/extensions/togeojson.js
trunk/mapbender/http/extensions/tokml.js
Log:
Update versions of kml and geojson import handlers (from mapbox project)
Modified: trunk/mapbender/http/extensions/togeojson.js
===================================================================
--- trunk/mapbender/http/extensions/togeojson.js 2015-07-13 07:34:40 UTC (rev 9246)
+++ trunk/mapbender/http/extensions/togeojson.js 2015-07-13 07:49:34 UTC (rev 9247)
@@ -1,4 +1,4 @@
-toGeoJSON = (function() {
+var toGeoJSON = (function() {
'use strict';
var removeSpace = (/\s*/g),
@@ -21,18 +21,18 @@
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]);
+ 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];
+ 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) || '';
+ return (x && x.textContent) || '';
}
// get one coordinate from a coordinate array, if any
function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
@@ -47,9 +47,22 @@
}
function coordPair(x) {
var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
- ele = get1(x, 'ele');
- if (ele) ll.push(parseFloat(nodeVal(ele)));
- return ll;
+ ele = get1(x, 'ele'),
+ // handle namespaced attribute in browser
+ heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
+ time = get1(x, 'time'),
+ e;
+ if (ele) {
+ e = parseFloat(nodeVal(ele));
+ if (!isNaN(e)) {
+ ll.push(e);
+ }
+ }
+ return {
+ coordinates: ll,
+ time: time ? nodeVal(time) : null,
+ heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
+ };
}
// create a new feature collection parent object
@@ -62,23 +75,27 @@
var serializer;
if (typeof XMLSerializer !== 'undefined') {
+ /* istanbul ignore next */
serializer = new XMLSerializer();
// only require xmldom in a node environment
} else if (typeof exports === 'object' && typeof process === 'object' && !process.browser) {
serializer = new (require('xmldom').XMLSerializer)();
}
- function xml2str(str) { return serializer.serializeToString(str); }
+ function xml2str(str) {
+ // IE9 will create a new XMLSerializer but it'll crash immediately.
+ if (str.xml !== undefined) return str.xml;
+ return serializer.serializeToString(str);
+ }
var t = {
- kml: function(doc, o) {
- o = o || {};
+ kml: function(doc) {
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'],
+ geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
// all root placemarks in the file
placemarks = get(doc, 'Placemark'),
styles = get(doc, 'Style');
@@ -92,8 +109,8 @@
function kmlColor(v) {
var color, opacity;
v = v || "";
- if (v.substr(0, 1) === "#") v = v.substr(1);
- if (v.length === 6 || v.length === 3) color = v;
+ if (v.substr(0, 1) === "#") { v = v.substr(1); }
+ if (v.length === 6 || v.length === 3) { color = v; }
if (v.length === 8) {
opacity = parseInt(v.substr(0, 2), 16) / 255;
color = v.substr(2);
@@ -102,30 +119,37 @@
}
function gxCoord(v) { return numarray(v.split(' ')); }
function gxCoords(root) {
- var elems = get(root, 'coord', 'gx'), coords = [];
+ var elems = get(root, 'coord', 'gx'), coords = [], times = [];
+ if (elems.length === 0) elems = get(root, 'gx:coord');
for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
- return coords;
+ var timeElems = get(root, 'when');
+ for (var i = 0; i < timeElems.length; i++) times.push(nodeVal(timeElems[i]));
+ return {
+ coords: coords,
+ times: times
+ };
}
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'));
+ var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
+ if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
+ if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
+ if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx: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') {
+ if (geotypes[i] === 'Point') {
geoms.push({
type: 'Point',
coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
});
- } else if (geotypes[i] == 'LineString') {
+ } else if (geotypes[i] === 'LineString') {
geoms.push({
type: 'LineString',
coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
});
- } else if (geotypes[i] == 'Polygon') {
+ } else if (geotypes[i] === 'Polygon') {
var rings = get(geomNode, 'LinearRing'),
coords = [];
for (k = 0; k < rings.length; k++) {
@@ -135,19 +159,25 @@
type: 'Polygon',
coordinates: coords
});
- } else if (geotypes[i] == 'Track') {
+ } else if (geotypes[i] === 'Track' ||
+ geotypes[i] === 'gx:Track') {
+ var track = gxCoords(geomNode);
geoms.push({
type: 'LineString',
- coordinates: gxCoords(geomNode)
+ coordinates: track.coords
});
+ if (track.times.length) coordTimes.push(track.times);
}
}
}
}
- return geoms;
+ return {
+ geoms: geoms,
+ coordTimes: coordTimes
+ };
}
function getPlacemark(root) {
- var geoms = getGeometry(root), i, properties = {},
+ var geomsAndTimes = getGeometry(root), i, properties = {},
name = nodeVal(get1(root, 'name')),
styleUrl = nodeVal(get1(root, 'styleUrl')),
description = nodeVal(get1(root, 'description')),
@@ -156,7 +186,7 @@
lineStyle = get1(root, 'LineStyle'),
polyStyle = get1(root, 'PolyStyle');
- if (!geoms.length) return [];
+ if (!geomsAndTimes.geoms.length) return [];
if (name) properties.name = name;
if (styleUrl && styleIndex[styleUrl]) {
properties.styleUrl = styleUrl;
@@ -199,49 +229,80 @@
properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
}
}
- return [{
+ if (geomsAndTimes.coordTimes.length) {
+ properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
+ geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
+ }
+ var feature = {
type: 'Feature',
- geometry: (geoms.length === 1) ? geoms[0] : {
+ geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
type: 'GeometryCollection',
- geometries: geoms
+ geometries: geomsAndTimes.geoms
},
properties: properties
- }];
+ };
+ if (attr(root, 'id')) feature.id = attr(root, 'id');
+ return [feature];
}
return gj;
},
- gpx: function(doc, o) {
- // console.log('test');
+ gpx: function(doc) {
var i,
tracks = get(doc, 'trk'),
routes = get(doc, 'rte'),
waypoints = get(doc, 'wpt'),
// a feature collection
- gj = fc();
+ gj = fc(),
+ feature;
for (i = 0; i < tracks.length; i++) {
- gj.features.push(getTrack(tracks[i]));
+ feature = getTrack(tracks[i]);
+ if (feature) gj.features.push(feature);
}
for (i = 0; i < routes.length; i++) {
- gj.features.push(getRoute(routes[i]));
+ feature = getRoute(routes[i]);
+ if (feature) gj.features.push(feature);
}
for (i = 0; i < waypoints.length; i++) {
gj.features.push(getPoint(waypoints[i]));
}
function getPoints(node, pointname) {
- var pts = get(node, pointname), line = [];
- for (var i = 0; i < pts.length; i++) {
- line.push(coordPair(pts[i]));
+ var pts = get(node, pointname),
+ line = [],
+ times = [],
+ heartRates = [],
+ l = pts.length;
+ if (l < 2) return {}; // Invalid line in GeoJSON
+ for (var i = 0; i < l; i++) {
+ var c = coordPair(pts[i]);
+ line.push(c.coordinates);
+ if (c.time) times.push(c.time);
+ if (c.heartRate) heartRates.push(c.heartRate);
}
- return line;
+ return {
+ line: line,
+ times: times,
+ heartRates: heartRates
+ };
}
function getTrack(node) {
- var segments = get(node, 'trkseg'), track = [];
+ var segments = get(node, 'trkseg'),
+ track = [],
+ times = [],
+ heartRates = [],
+ line;
for (var i = 0; i < segments.length; i++) {
- track.push(getPoints(segments[i], 'trkpt'));
+ line = getPoints(segments[i], 'trkpt');
+ if (line.line) track.push(line.line);
+ if (line.times && line.times.length) times.push(line.times);
+ if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
}
+ if (track.length === 0) return;
+ var properties = getProperties(node);
+ if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
+ if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
return {
type: 'Feature',
- properties: getProperties(node),
+ properties: properties,
geometry: {
type: track.length === 1 ? 'LineString' : 'MultiLineString',
coordinates: track.length === 1 ? track[0] : track
@@ -249,14 +310,17 @@
};
}
function getRoute(node) {
- return {
+ var line = getPoints(node, 'rtept');
+ if (!line) return;
+ var routeObj = {
type: 'Feature',
properties: getProperties(node),
geometry: {
type: 'LineString',
- coordinates: getPoints(node, 'rtept')
+ coordinates: line.line
}
};
+ return routeObj;
}
function getPoint(node) {
var prop = getProperties(node);
@@ -266,7 +330,7 @@
properties: prop,
geometry: {
type: 'Point',
- coordinates: coordPair(node)
+ coordinates: coordPair(node).coordinates
}
};
}
Modified: trunk/mapbender/http/extensions/tokml.js
===================================================================
--- trunk/mapbender/http/extensions/tokml.js 2015-07-13 07:34:40 UTC (rev 9246)
+++ trunk/mapbender/http/extensions/tokml.js 2015-07-13 07:49:34 UTC (rev 9247)
@@ -1,15 +1,17 @@
-!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.tokml=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.tokml = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var strxml = require('strxml'),
tag = strxml.tag,
encode = strxml.encode;
module.exports = function tokml(geojson, options) {
+
options = options || {
documentName: undefined,
documentDescription: undefined,
name: 'name',
description: 'description',
- simplestyle: false
+ simplestyle: false,
+ timestamp: 'timestamp'
};
return '<?xml version="1.0" encoding="UTF-8"?>' +
@@ -17,7 +19,6 @@
tag('Document',
documentName(options) +
documentDescription(options) +
- documentMetadata(geojson,options) + // add metadata to featureCollections
root(geojson, options)
), [['xmlns', 'http://www.opengis.net/kml/2.2']]);
};
@@ -36,8 +37,9 @@
return styleDefinition + tag('Placemark',
name(_.properties, options) +
description(_.properties, options) +
- geometryString +
extendeddata(_.properties) +
+ timestamp(_.properties, options) +
+ geometryString +
styleReference);
};
}
@@ -57,27 +59,12 @@
properties: {}
});
}
- return '';
}
function documentName(options) {
return (options.documentName !== undefined) ? tag('name', options.documentName) : '';
}
-function documentMetadata(geojson,options) {
-
- if (geojson.type != 'Feature') {
-
- var metadata = {};
- for(var key in geojson){
- if(key!= 'features'){
- metadata[key]= geojson[key];
- }
- }
- extendeddata(metadata);
- return extendeddata(metadata);
- }
-}
function documentDescription(options) {
return (options.documentDescription !== undefined) ? tag('description', options.documentDescription) : '';
}
@@ -90,6 +77,10 @@
return _[options.description] ? tag('description', encode(_[options.description])) : '';
}
+function timestamp(_, options) {
+ return _[options.timestamp] ? tag('TimeStamp', tag('when', encode(_[options.timestamp]))) : '';
+}
+
// ## Geometry Types
//
// https://developers.google.com/kml/documentation/kmlreference#geometry
@@ -153,7 +144,6 @@
// ## Data
function extendeddata(_) {
-
return tag('ExtendedData', pairs(_).map(data).join(''));
}
@@ -232,15 +222,6 @@
/**
* @param {string} el element name
- * @param {array} attributes array of pairs
- * @returns {string}
- */
-function tagOpen(el, attributes) {
- return '<' + el + attr(attributes) + '>';
-}
-
-/**
- * @param {string} el element name
* @param {string} contents innerXML
* @param {array} attributes array of pairs
* @returns {string}
@@ -260,6 +241,5 @@
.replace(/"/g, '"');
}
-},{}]},{},[1])
-(1)
+},{}]},{},[1])(1)
});
More information about the Mapbender_commits
mailing list