UNPKG

tokml

Version:
469 lines (426 loc) 14.5 kB
;(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){ module.exports = function tokml(geojson, options) { options = options || { name: 'name', description: 'description', }; return '<?xml version="1.0" encoding="UTF-8"?>' + tag('kml', tag('Document', geojson.features.map(feature(options)).join('') ), [['xmlns', 'http://www.opengis.net/kml/2.2']]); }; function feature(options) { return function(_) { return tag('Placemark', name(_.properties, options) + description(_.properties, options) + geometry.any(_.geometry) + extendeddata(_.properties)); }; } function name(_, options) { return (_[options.name]) ? tag('name', encode(_[options.name])) : ''; } function description(_, options) { return (_[options.description]) ? tag('description', encode(_[options.description])) : ''; } // ## 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(_) { 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(_) { return tag('MultiGeometry', _.coordinates.map(function(c) { return geometry.Point({ coordinates: c }); }).join('')); }, MultiPolygon: function(_) { return tag('MultiGeometry', _.coordinates.map(function(c) { return geometry.Polygon({ coordinates: c }); }).join('')); }, MultiLineString: function(_) { return tag('MultiGeometry', _.coordinates.map(function(c) { return geometry.LineString({ coordinates: c }); }).join('')); }, GeometryCollection: function(_) { return tag('MultiGeometry', _.geometries.map(geometry.any).join('')); }, any: function(_) { if (geometry[_.type]) { return geometry[_.type](_); } else { } } }; 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', encode(_[1]), [['name', encode(_[0])]]); } // ## Helpers function pairs(_) { var o = []; for (var i in _) o.push([i, _[i]]); return o; } function attr(_) { return _ ? (' ' + _.map(function(a) { return a[0] + '="' + a[1] + '"'; }).join(' ')) : ''; } function tag(el, contents, attributes) { return '<' + el + attr(attributes) + '>' + contents + '</' + el + '>'; } function encode(_) { return _.replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;'); } },{}],2:[function(require,module,exports){ function xhr(url, callback, cors) { var sent = false; if (typeof window.XMLHttpRequest === 'undefined') { return callback(Error('Browser not supported')); } if (typeof cors === 'undefined') { var m = url.match(/^\s*https?:\/\/[^\/]*/); cors = m && (m[0] !== location.protocol + '//' + location.domain + (location.port ? ':' + location.port : '')); } var x; function isSuccessful(status) { return status >= 200 && status < 300 || status === 304; } if (cors && ( // IE7-9 Quirks & Compatibility typeof window.XDomainRequest === 'object' || // IE9 Standards mode typeof window.XDomainRequest === 'function' )) { // IE8-10 x = new window.XDomainRequest(); // Ensure callback is never called synchronously, i.e., before // x.send() returns (this has been observed in the wild). // See https://github.com/mapbox/mapbox.js/issues/472 var original = callback; callback = function() { if (sent) { original.apply(this, arguments); } else { var that = this, args = arguments; setTimeout(function() { original.apply(that, args); }, 0); } } } else { x = new window.XMLHttpRequest(); } function loaded() { if ( // XDomainRequest x.status === undefined || // modern browsers isSuccessful(x.status)) callback.call(x, null, x); else callback.call(x, x, null); } // Both `onreadystatechange` and `onload` can fire. `onreadystatechange` // has [been supported for longer](http://stackoverflow.com/a/9181508/229001). if ('onload' in x) { x.onload = loaded; } else { x.onreadystatechange = function readystate() { if (x.readyState === 4) { loaded(); } }; } // Call the callback with the XMLHttpRequest object as an error and prevent // it from ever being called again by reassigning it to `noop` x.onerror = function error(evt) { // XDomainRequest provides no evt parameter callback.call(this, evt || true, null); callback = function() { }; }; // IE9 must have onprogress be set to a unique function. x.onprogress = function() { }; x.ontimeout = function(evt) { callback.call(this, evt, null); callback = function() { }; }; x.onabort = function(evt) { callback.call(this, evt, null); callback = function() { }; }; // GET is the only supported HTTP Verb by XDomainRequest and is the // only one supported here. x.open('GET', url, true); // Send the request. Sending data is not supported. x.send(null); sent = true; return x; } if (typeof module !== 'undefined') module.exports = xhr; },{}],3:[function(require,module,exports){ /* FileSaver.js * A saveAs() FileSaver implementation. * 2013-01-23 * * By Eli Grey, http://eligrey.com * License: X11/MIT * See LICENSE.md */ /*global self */ /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, plusplus: true */ /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ var saveAs = saveAs || (navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator)) || (function(view) { "use strict"; var doc = view.document // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet , get_URL = function() { return view.URL || view.webkitURL || view; } , URL = view.URL || view.webkitURL || view , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") , can_use_save_link = !view.externalHost && "download" in save_link , click = function(node) { var event = doc.createEvent("MouseEvents"); event.initMouseEvent( "click", true, false, view, 0, 0, 0, 0, 0 , false, false, false, false, 0, null ); node.dispatchEvent(event); } , webkit_req_fs = view.webkitRequestFileSystem , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem , throw_outside = function (ex) { (view.setImmediate || view.setTimeout)(function() { throw ex; }, 0); } , force_saveable_type = "application/octet-stream" , fs_min_size = 0 , deletion_queue = [] , process_deletion_queue = function() { var i = deletion_queue.length; while (i--) { var file = deletion_queue[i]; if (typeof file === "string") { // file is an object URL URL.revokeObjectURL(file); } else { // file is a File file.remove(); } } deletion_queue.length = 0; // clear queue } , dispatch = function(filesaver, event_types, event) { event_types = [].concat(event_types); var i = event_types.length; while (i--) { var listener = filesaver["on" + event_types[i]]; if (typeof listener === "function") { try { listener.call(filesaver, event || filesaver); } catch (ex) { throw_outside(ex); } } } } , FileSaver = function(blob, name) { // First try a.download, then web filesystem, then object URLs var filesaver = this , type = blob.type , blob_changed = false , object_url , target_view , get_object_url = function() { var object_url = get_URL().createObjectURL(blob); deletion_queue.push(object_url); return object_url; } , dispatch_all = function() { dispatch(filesaver, "writestart progress write writeend".split(" ")); } // on any filesys errors revert to saving with object URLs , fs_error = function() { // don't create more object URLs than needed if (blob_changed || !object_url) { object_url = get_object_url(blob); } if (target_view) { target_view.location.href = object_url; } else { window.open(object_url, "_blank"); } filesaver.readyState = filesaver.DONE; dispatch_all(); } , abortable = function(func) { return function() { if (filesaver.readyState !== filesaver.DONE) { return func.apply(this, arguments); } }; } , create_if_not_found = {create: true, exclusive: false} , slice ; filesaver.readyState = filesaver.INIT; if (!name) { name = "download"; } if (can_use_save_link) { object_url = get_object_url(blob); save_link.href = object_url; save_link.download = name; click(save_link); filesaver.readyState = filesaver.DONE; dispatch_all(); return; } // Object and web filesystem URLs have a problem saving in Google Chrome when // viewed in a tab, so I force save with application/octet-stream // http://code.google.com/p/chromium/issues/detail?id=91158 if (view.chrome && type && type !== force_saveable_type) { slice = blob.slice || blob.webkitSlice; blob = slice.call(blob, 0, blob.size, force_saveable_type); blob_changed = true; } // Since I can't be sure that the guessed media type will trigger a download // in WebKit, I append .download to the filename. // https://bugs.webkit.org/show_bug.cgi?id=65440 if (webkit_req_fs && name !== "download") { name += ".download"; } if (type === force_saveable_type || webkit_req_fs) { target_view = view; } if (!req_fs) { fs_error(); return; } fs_min_size += blob.size; req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { var save = function() { dir.getFile(name, create_if_not_found, abortable(function(file) { file.createWriter(abortable(function(writer) { writer.onwriteend = function(event) { target_view.location.href = file.toURL(); deletion_queue.push(file); filesaver.readyState = filesaver.DONE; dispatch(filesaver, "writeend", event); }; writer.onerror = function() { var error = writer.error; if (error.code !== error.ABORT_ERR) { fs_error(); } }; "writestart progress write abort".split(" ").forEach(function(event) { writer["on" + event] = filesaver["on" + event]; }); writer.write(blob); filesaver.abort = function() { writer.abort(); filesaver.readyState = filesaver.DONE; }; filesaver.readyState = filesaver.WRITING; }), fs_error); }), fs_error); }; dir.getFile(name, {create: false}, abortable(function(file) { // delete file if it already exists file.remove(); save(); }), abortable(function(ex) { if (ex.code === ex.NOT_FOUND_ERR) { save(); } else { fs_error(); } })); }), fs_error); }), fs_error); } , FS_proto = FileSaver.prototype , saveAs = function(blob, name) { return new FileSaver(blob, name); } ; FS_proto.abort = function() { var filesaver = this; filesaver.readyState = filesaver.DONE; dispatch(filesaver, "abort"); }; FS_proto.readyState = FS_proto.INIT = 0; FS_proto.WRITING = 1; FS_proto.DONE = 2; FS_proto.error = FS_proto.onwritestart = FS_proto.onprogress = FS_proto.onwrite = FS_proto.onabort = FS_proto.onerror = FS_proto.onwriteend = null; view.addEventListener("unload", process_deletion_queue, false); return saveAs; }(self)); if (typeof module !== 'undefined') module.exports = saveAs; },{}],4:[function(require,module,exports){ var convert = document.getElementById('convert'), convertRaw = document.getElementById('convert-raw'), mapGeoJSON = document.getElementById('map-geojson'), mapid = document.getElementById('map-id'), xhr = require('corslite'), saveAs = require('filesaver.js'), tokml = require('../'); convert.onclick = function() { xhr('http://api.tiles.mapbox.com/v3/' + mapid.value + '/markers.geojson', onload, true); function onload(err, resp) { if (err) return alert(err); else return run(JSON.parse(resp.response)); } }; convertRaw.onclick = function() { run(JSON.parse(mapGeoJSON.value)); }; function run(gj) { saveAs(new Blob([tokml(gj)], { type: 'application/vnd.google-earth.kml+xml' }), 'map.kml'); } },{"../":1,"corslite":2,"filesaver.js":3}]},{},[4]) ;