bmh_cesium/public/lib/kml/tokml.js
2025-03-10 07:23:50 +08:00

344 lines
11 KiB
JavaScript

(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,
timestamp: 'timestamp'
};
return '<?xml version="1.0" encoding="UTF-8"?>' +
tag('kml',
tag('Document',
documentName(options) +
documentDescription(options) +
root(geojson, options)
), [['xmlns', 'http://www.opengis.net/kml/2.2']]);
};
function feature(options, styleHashesArray) {
return function(_) {
if (!_.properties || !geometry.valid(_.geometry)) return '';
var geometryString = geometry.any(_.geometry);
if (!geometryString) return '';
var styleDefinition = '',
styleReference = '';
if (options.simplestyle) {
var styleHash = hashStyle(_.properties);
if (styleHash) {
if (geometry.isPoint(_.geometry) && hasMarkerStyle(_.properties)) {
if (styleHashesArray.indexOf(styleHash) === -1) {
styleDefinition = markerStyle(_.properties, styleHash);
styleHashesArray.push(styleHash);
}
styleReference = tag('styleUrl', '#' + styleHash);
} else if ((geometry.isPolygon(_.geometry) || geometry.isLine(_.geometry)) &&
hasPolygonAndLineStyle(_.properties)) {
if (styleHashesArray.indexOf(styleHash) === -1) {
styleDefinition = polygonAndLineStyle(_.properties, styleHash);
styleHashesArray.push(styleHash);
}
styleReference = tag('styleUrl', '#' + styleHash);
}
// Note that style of GeometryCollection / MultiGeometry is not supported
}
}
return styleDefinition + tag('Placemark',
name(_.properties, options) +
description(_.properties, options) +
extendeddata(_.properties) +
timestamp(_.properties, options) +
geometryString +
styleReference);
};
}
function root(_, options) {
if (!_.type) return '';
var styleHashesArray = [];
switch (_.type) {
case 'FeatureCollection':
if (!_.features) return '';
return _.features.map(feature(options, styleHashesArray)).join('');
case 'Feature':
return feature(options, styleHashesArray)(_);
default:
return feature(options, styleHashesArray)({
type: 'Feature',
geometry: _,
properties: {}
});
}
}
function documentName(options) {
return (options.documentName !== undefined) ? tag('name', options.documentName) : '';
}
function documentDescription(options) {
return (options.documentDescription !== undefined) ? tag('description', options.documentDescription) : '';
}
function name(_, options) {
return _[options.name] ? tag('name', encode(_[options.name])) : '';
}
function description(_, options) {
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
var geometry = {
Point: function(_) {
return tag('Point', tag('coordinates', _.coordinates.join(',')));
},
LineString: function(_) {
return tag('LineString', tag('coordinates', linearring(_.coordinates)));
},
Polygon: function(_) {
if (!_.coordinates.length) return '';
var outer = _.coordinates[0],
inner = _.coordinates.slice(1),
outerRing = tag('outerBoundaryIs',
tag('LinearRing', tag('coordinates', linearring(outer)))),
innerRings = inner.map(function(i) {
return tag('innerBoundaryIs',
tag('LinearRing', tag('coordinates', linearring(i))));
}).join('');
return tag('Polygon', outerRing + innerRings);
},
MultiPoint: function(_) {
if (!_.coordinates.length) return '';
return tag('MultiGeometry', _.coordinates.map(function(c) {
return geometry.Point({ coordinates: c });
}).join(''));
},
MultiPolygon: function(_) {
if (!_.coordinates.length) return '';
return tag('MultiGeometry', _.coordinates.map(function(c) {
return geometry.Polygon({ coordinates: c });
}).join(''));
},
MultiLineString: function(_) {
if (!_.coordinates.length) return '';
return tag('MultiGeometry', _.coordinates.map(function(c) {
return geometry.LineString({ coordinates: c });
}).join(''));
},
GeometryCollection: function(_) {
return tag('MultiGeometry',
_.geometries.map(geometry.any).join(''));
},
valid: function(_) {
return _ && _.type && (_.coordinates ||
_.type === 'GeometryCollection' && _.geometries && _.geometries.every(geometry.valid));
},
any: function(_) {
if (geometry[_.type]) {
return geometry[_.type](_);
} else {
return '';
}
},
isPoint: function(_) {
return _.type === 'Point' ||
_.type === 'MultiPoint';
},
isPolygon: function(_) {
return _.type === 'Polygon' ||
_.type === 'MultiPolygon';
},
isLine: function(_) {
return _.type === 'LineString' ||
_.type === 'MultiLineString';
}
};
function linearring(_) {
return _.map(function(cds) { return cds.join(','); }).join(' ');
}
// ## Data
function extendeddata(_) {
return tag('ExtendedData', pairs(_).map(data).join(''));
}
function data(_) {
return tag('Data', tag('value', encode(_[1])), [['name', encode(_[0])]]);
}
// ## Marker style
function hasMarkerStyle(_) {
return !!(_['marker-size'] || _['marker-symbol'] || _['marker-color']);
}
function markerStyle(_, styleHash) {
return tag('Style',
tag('IconStyle',
tag('Icon',
tag('href', iconUrl(_)))) +
iconSize(_), [['id', styleHash]]);
}
function iconUrl(_) {
var size = _['marker-size'] || 'medium',
symbol = _['marker-symbol'] ? '-' + _['marker-symbol'] : '',
color = (_['marker-color'] || '7e7e7e').replace('#', '');
return 'https://api.tiles.mapbox.com/v3/marker/' + 'pin-' + size.charAt(0) +
symbol + '+' + color + '.png';
}
function iconSize(_) {
return tag('hotSpot', '', [
['xunits', 'fraction'],
['yunits', 'fraction'],
['x', 0.5],
['y', 0.5]
]);
}
// ## Polygon and Line style
function hasPolygonAndLineStyle(_) {
for (var key in _) {
if ({
"stroke": true,
"stroke-opacity": true,
"stroke-width": true,
"fill": true,
"fill-opacity": true
}[key]) return true;
}
}
function polygonAndLineStyle(_, styleHash) {
var lineStyle = tag('LineStyle', [
tag('color', hexToKmlColor(_['stroke'], _['stroke-opacity']) || 'ff555555') +
tag('width', _['stroke-width'] === undefined ? 2 : _['stroke-width'])
]);
var polyStyle = '';
if (_['fill'] || _['fill-opacity']) {
polyStyle = tag('PolyStyle', [
tag('color', hexToKmlColor(_['fill'], _['fill-opacity']) || '88555555')
]);
}
return tag('Style', lineStyle + polyStyle, [['id', styleHash]]);
}
// ## Style helpers
function hashStyle(_) {
var hash = '';
if (_['marker-symbol']) hash = hash + 'ms' + _['marker-symbol'];
if (_['marker-color']) hash = hash + 'mc' + _['marker-color'].replace('#', '');
if (_['marker-size']) hash = hash + 'ms' + _['marker-size'];
if (_['stroke']) hash = hash + 's' + _['stroke'].replace('#', '');
if (_['stroke-width']) hash = hash + 'sw' + _['stroke-width'].toString().replace('.', '');
if (_['stroke-opacity']) hash = hash + 'mo' + _['stroke-opacity'].toString().replace('.', '');
if (_['fill']) hash = hash + 'f' + _['fill'].replace('#', '');
if (_['fill-opacity']) hash = hash + 'fo' + _['fill-opacity'].toString().replace('.', '');
return hash;
}
function hexToKmlColor(hexColor, opacity) {
if (typeof hexColor !== 'string') return '';
hexColor = hexColor.replace('#', '').toLowerCase();
if (hexColor.length === 3) {
hexColor = hexColor[0] + hexColor[0] +
hexColor[1] + hexColor[1] +
hexColor[2] + hexColor[2];
} else if (hexColor.length !== 6) {
return '';
}
var r = hexColor[0] + hexColor[1];
var g = hexColor[2] + hexColor[3];
var b = hexColor[4] + hexColor[5];
var o = 'ff';
if (typeof opacity === 'number' && opacity >= 0.0 && opacity <= 1.0) {
o = (opacity * 255).toString(16);
if (o.indexOf('.') > -1) o = o.substr(0, o.indexOf('.'));
if (o.length < 2) o = '0' + o;
}
return o + b + g + r;
}
// ## General helpers
function pairs(_) {
var o = [];
for (var i in _) o.push([i, _[i]]);
return o;
}
},{"strxml":2}],2:[function(require,module,exports){
module.exports.attr = attr;
module.exports.tagClose = tagClose;
module.exports.tag = tag;
module.exports.encode = encode;
/**
* @param {array} _ an array of attributes
* @returns {string}
*/
function attr(_) {
return (_ && _.length) ? (' ' + _.map(function(a) {
return a[0] + '="' + a[1] + '"';
}).join(' ')) : '';
}
/**
* @param {string} el element name
* @param {array} attributes array of pairs
* @returns {string}
*/
function tagClose(el, attributes) {
return '<' + el + attr(attributes) + '/>';
}
/**
* @param {string} el element name
* @param {string} contents innerXML
* @param {array} attributes array of pairs
* @returns {string}
*/
function tag(el, contents, attributes) {
return '<' + el + attr(attributes) + '>' + contents + '</' + el + '>';
}
/**
* @param {string} _ a string of attribute
* @returns {string}
*/
function encode(_) {
if(_==null ||_==undefined)return '';
return (_ === null ? '' : _.toString()).replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
},{}]},{},[1])(1)
});