[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