Last active
May 2, 2017 14:17
-
-
Save fxi/b7f1af5981432296bfafec70a95fd9b6 to your computer and use it in GitHub Desktop.
Revisions
-
fxi revised this gist
Sep 1, 2016 . 2 changed files with 25 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -117,8 +117,17 @@ if (window.File && window.FileReader && window.FileList && window.Blob) { } }; // launch process try { w.postMessage(res); }catch(err){ alert("An error occured, quick ! check the console !"); console.log({ res : res, err : err }); } }; }; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -50,7 +50,6 @@ onmessage = function(e) { // start timer timerStart(); /** * validation : geojson validation with geojsonhint */ @@ -145,14 +144,19 @@ onmessage = function(e) { * Avoid multi type : we don't handle them for now */ var geomType = []; if( gJson.features ){ // array of types in data geomTypes = gJson.features .map(function(x){ return typeSwitcher[x.geometry.type]; }) .filter(function(v,i,s){ return s.indexOf(v) === i; }); }else{ geomTypes = [typeSwitcher[gJson.geometry.type]]; } postMessage({ @@ -230,10 +234,12 @@ onmessage = function(e) { layer: dummyStyle[typ] }); } catch(err) { console.log(err); postMessage({ progress: 100, errorMessage : "An error occured, yey ! Quick, check the console !" }); } }; -
fxi revised this gist
Sep 1, 2016 . 2 changed files with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -76,7 +76,7 @@ if (window.File && window.FileReader && window.FileList && window.Blob) { true, theFile.name, m.progress, theFile.name + ": " + m.message ); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -148,7 +148,7 @@ onmessage = function(e) { // array of types in data var geomTypes = gJson.features .map(function(x){ return typeSwitcher[x.geometry.type]; }) .filter(function(v,i,s){ return s.indexOf(v) === i; @@ -189,7 +189,7 @@ onmessage = function(e) { var colB = randomHsl(0.5, ran); // Set default type from geojson type var typ = geomTypes[0]; // Set up default style var dummyStyle = { -
fxi revised this gist
Sep 1, 2016 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -141,7 +141,8 @@ if (window.File && window.FileReader && window.FileList && window.Blob) { f = files[i]; // Only process geojson files. Validate later. if (f.name.toLowerCase().indexOf(".geojson") == -1) { alert(f.name + " not supported"); continue; } // get a new reader -
fxi revised this gist
Sep 1, 2016 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,3 @@ Experimental work with mapbox gl js, web workers and geojsonhint to create new layers by drag and dropping geojson data. -
fxi revised this gist
Sep 1, 2016 . No changes.There are no files selected for viewing
-
fxi revised this gist
Sep 1, 2016 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,4 @@ # Drop multiple large geojson in mapbox gl js Experimental work with mapbox gl js, web workers and geojsonhint to create new layers by drag and dropping geojson data. -
fxi revised this gist
Sep 1, 2016 . 2 changed files with 10 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,16 +2,14 @@ mapboxgl.accessToken = 'pk.eyJ1IjoidW5lcGdyaWQiLCJhIjoiY2lzZnowenUwMDAzdjJubzZyZ3R1bjIzZyJ9.uyP-RWjY-94qCVajU0u8KA'; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/dark-v9', center: [-14.66,-23.64], zoom: 3 }); // object to hold geojson var data = {}; // test if file api is available if (window.File && window.FileReader && window.FileList && window.Blob) { @@ -59,7 +57,7 @@ if (window.File && window.FileReader && window.FileList && window.Blob) { var startWorker = function(theFile) { return function(e) { // Create a worker to handle this file var w = new Worker("handleReadJson.js"); // parse file content before passing to worker. var gJson = JSON.parse(e.target.result); @@ -107,7 +105,7 @@ if (window.File && window.FileReader && window.FileList && window.Blob) { "data": gJson }); // add layer map.addLayer(m.layer,"place-village"); // set progress to max data[m.id] = gJson; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -68,8 +68,8 @@ onmessage = function(e) { // set a message with summary var logMessage = " geojson validation " + " n errors = " + errors.length + " n warnings = " + warnings.length + " done in" + timerLapString(); console.log(fileName + ":" + logMessage); @@ -185,8 +185,8 @@ onmessage = function(e) { var id = "mgl_drop_" + randomString(5) + "_" + fileName ; // Set random color var ran = Math.random(); var colA = randomHsl(0.1, ran); var colB = randomHsl(0.5, ran); // Set default type from geojson type var typ = typeSwitcher[geomTypes[0]]; -
fxi revised this gist
Sep 1, 2016 . No changes.There are no files selected for viewing
-
fxi revised this gist
Sep 1, 2016 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,13 +6,13 @@ <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <meta http-equiv="cache-control" content="Public"> <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.23.0/mapbox-gl.css' rel='stylesheet' /> <link href='progress.css' rel='stylesheet' /> <link href='app.css' rel='stylesheet' /> </head> <body> <div id='map'></div> <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.23.0/mapbox-gl.js'></script> <script src='helpers.js'></script> <script src='app.js'></script> </body> </html> -
fxi revised this gist
Sep 1, 2016 . 9 changed files with 0 additions and 2266 deletions.There are no files selected for viewing
File renamed without changes.File renamed without changes.This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,268 +0,0 @@ File renamed without changes.File renamed without changes.This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,1566 +0,0 @@ File renamed without changes.File renamed without changes. -
fxi revised this gist
Sep 1, 2016 . No changes.There are no files selected for viewing
-
fxi revised this gist
Sep 1, 2016 . 5 changed files with 9 additions and 445 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,183 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,254 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,4 @@ body { margin:0; padding:0; } #map { position:absolute; top:0; bottom:0; width:100%; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,3 @@ .loading-screen { background-color : rgba(47,47,47,0.6); @@ -12,7 +9,6 @@ body { margin:0; padding:0; } } .loading-container { font-family : "Lucida Console", Monaco, monospace; color: #0f0; position:absolute; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,15 +2,16 @@ <html> <head> <meta charset='utf-8' /> <title>Drop geojson</title> <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <meta http-equiv="cache-control" content="Public"> <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.23.0/mapbox-gl.css' rel='stylesheet' /> <link href='css/progress.css' rel='stylesheet' /> <link href='css/app.css' rel='stylesheet' /> </head> <body> <div id='map'></div> <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.23.0/mapbox-gl.js'></script> <script src='js/helpers.js'></script> <script src='js/app.js'></script> </body> -
fxi revised this gist
Sep 1, 2016 . 11 changed files with 3307 additions and 185 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,183 @@ postMessage({ progress : 0, message : "start" }); onmessage = function(e) { var dat = e.data; // set timing function timerVal = 0; var timerStart = function() { timerVal = new Date(); }; var timerLap = function() { var lap = new Date() - timerVal; timerStart(); return lap; }; var timerLapString = function() { return "( " + timerLap() + " ms)"; }; timerStart(); // Parse json console.log(dat); var gJson = JSON.parse(dat.json); postMessage({ progress : 55, message :" parsed json in " + timerLapString() }); console.log(self); // Validation var messages = geojsonhint.hint(gJson); var errors = []; var nErrors = 0; var nWarnings = 0; messages.forEach(function(x) { if (x.level == "warn") { nWarnings++; } else { errors.push(x); nErrors++; } }); postMessage({ progress : 60, message : " json validation " + " n errors=" + nErrors + " n warnings =" + nWarnings + timerLapString() }); if (errors.length > 0) { var msgErrors = errors.length() + "found. check the console for more info"; postMessage({ progress : 100, message : msgErrors }); console.log(errors); alert(msgErrors); return ; } // get extent with geojsonExtent mapbox plugin var extent = turf.bbox(gJson); //var extent = geojsonExtent(gJson); postMessage({ progress : 80, message : " extent found in " + timerLapString() }); // arra of types in data var geomTypes = []; // Get type for each feature gJson.features.forEach(function(x) { var g = x.geometry.type; if (geomTypes.length === 0 || geomTypes.indexOf(g) == -1) { geomTypes.push(g); } }); postMessage({ progress : 90, message : " geom types found in " + timerLapString() }); // if more than one type, return an error if (geomTypes.length > 1) { var msg = "Multi geometry not yet implemented"; postMessage({ progress : 100, message : msg }); alert(msg); return ; } // Set random id for source and layer var id = "mgl_drop_" + geomTypes[0] + "_" + randomString(5); // Set random color var ran = Math.random(); var colA = randomHsl(0.6, ran); var colB = randomHsl(0.8, ran); // Set default type from geojson type var typ = typeSwitcher[geomTypes[0]]; // Set up default style var dummyStyle = { "circle": { "id": id, "source": id, "type": typ, "paint": { "circle-color": colA } }, "fill": { "id": id, "source": id, "type": typ, "paint": { "fill-color": colA, "fill-outline-color": colB } }, "line": { "id": id, "source": id, "type": typ, "paint": { "line-color": colA, "line-width": 10 } } }; postMessage({ progress : 98, message : "Style done." }); return; //// Add source and layer; //map.fitBounds(extent); //map.addSource(id, { //type: 'geojson', //data: gJson //}); //progressScreen(true, theFile.name, 90, theFile.name + " add layer" + timerLapString()); //map.addLayer(dummyStyle[typ]); //progressScreen(true, theFile.name, 95, theFile.name + " add layer" + timerLapString()); }; //var handleReadGeoJson = function(theFile) { //return function(e) { //} //}; //}; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,254 @@ /** * Generate a random string of the given length * @param {integer} n Number of character * @return {string} random string */ var randomString = function(n) { var result = ""; if (!n) n = 5; var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < n; i++) result += characters.charAt(Math.floor(Math.random() * characters.length)); return result; }; /** * Generate a random hsla color string, with fixed saturation and lightness * @param {number} opacity opacity from 0 to 1 * @param {number} random value from 0 to 1 * @param {number} saturation from 0 to 100 * @param {number} lightness from 0 to 100 */ var randomHsl = function(opacity, random, saturation, lightness) { if (!opacity) opacity = 1; if (!saturation) saturation = 100; if (!lightness) lightness = 50; if (!random) random = Math.random(); res = "hsla(" + (random * 360) + ", " + saturation + "% " + ", " + lightness + "% " + ", " + opacity + ")"; return res; }; /** * Remove multiple layers by prefix * @param {object} map Map object * @param {string} prefix Prefix to search for in layers, if something found, remove it * @return {array} List of removed layer */ var removeLayersByPrefix = function(map, prefix) { var result = []; if (map) { // no method to get all layers ? var layers = map.style._layers; for (var l in layers) { if (l.indexOf(prefix) > -1) { map.removeLayer(l); result.push(l); } } } return result; }; var progressScreen = function(enable, id, percent, text ) { console.log(text); lScreen = document.getElementsByClassName("loading-screen")[0]; if (!enable) { if (lScreen) lScreen.remove(); return; } if (!id || !percent || !text) return; if (!lScreen && enable) { lBody = document.getElementsByTagName("body")[0]; lScreen = document.createElement("div"); lScreen.className = "loading-screen"; lScreenContainer = document.createElement("div"); lScreenContainer.className = "loading-container"; lScreen.appendChild(lScreenContainer); lBody.appendChild(lScreen); } lItem = document.getElementById(id); //lScreenContainer = lScreen.getElementsByClassName("loading-container")[0]; //lItem = lScreenContainer.querySelector("#" + id); if (!lItem) { lItem = document.createElement("div"); lItem.className = "loading-item"; lItem.setAttribute("id", id); pBarIn = document.createElement("div"); pBarIn.className = "loading-bar-in"; pBarOut = document.createElement("div"); pBarOut.className = "loading-bar-out"; pBarTxt = document.createElement("div"); pBarTxt.className = "loading-bar-txt"; pBarOut.appendChild(pBarIn); lItem.appendChild(pBarTxt); lItem.appendChild(pBarOut); lScreenContainer.appendChild(lItem); } else { pBarIn = lItem.getElementsByClassName("loading-bar-in")[0]; pBarTxt = lItem.getElementsByClassName("loading-bar-txt")[0]; } if (percent >= 100) { lItem = document.getElementById(id); if (lItem) lItem.remove(); } else { pBarIn.style.width = percent + "%"; pBarTxt.innerHTML = text; } lItems = lScreenContainer.getElementsByClassName("loading-item"); if (lItems.length === 0) progressScreen(false); }; // geojson type to mapbox gl type var typeSwitcher = { "Point": "circle", "MultiPoint": "line", "LineString": "line", "MultiLineString": "line", "Polygon": "fill", "MultiPolygon": "fill", "GeometryCollection": "fill" }; // mapbox gl init mapboxgl.accessToken = 'pk.eyJ1IjoidW5lcGdyaWQiLCJhIjoiY2lzZnowenUwMDAzdjJubzZyZ3R1bjIzZyJ9.uyP-RWjY-94qCVajU0u8KA'; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v9', center: [15.6, -4.3], zoom: 10 }); // test if file api is available if (window.File && window.FileReader && window.FileList && window.Blob) { // handle read geojson // Update progress var updateProgress = function(theFile) { return function(e) { // evt is an ProgressEvent. 100/2 as loading is ~ half the process if (e.lengthComputable) { var percentLoaded = Math.round((e.loaded / e.total) * 50); progressScreen(true, theFile.name, percentLoaded, theFile.name + " loading (" + percentLoaded * 2 + "%)"); } }; }; var startProgress = function(theFile) { return function(e) { progressScreen(true, theFile.name, 1, theFile.name + " init .. "); }; }; var errorProgress = function(theFile) { return function(e) { progressScreen(true, theFile.name, 100, theFile.name + "stop .. "); }; }; var startWorker = function(theFile){ return function(e){ var res = { json : e.target.result, fileName : theFile.name }; var w = new Worker("handleReadJson.js"); w.onmessage = function(e){ var m = e.data; progressScreen(true, theFile.name,m.progress, theFile.name + ":" + m.message ); if(m.progress == 100){ w.terminate(); } }; w.postMessage(res); }; }; var updateLayerList = function(theFile) { return function(e) { progressScreen(true, theFile.name, 100, theFile.name + " Done. "); }; }; // handle drop event var handleDropGeojson = function(evt) { evt.stopPropagation(); evt.preventDefault(); var files = evt.dataTransfer.files; var nFiles = files.length; var incFile = 100 / nFiles; var progressBar = 0; // In case of multiple file, loop on them for (var i = 0; i < nFiles; i++) { f = files[i]; // Only process geojson files. Validate later. if (f.name.indexOf(".geojson") == -1) { continue; } var reader = new FileReader(); reader.onloadstart = (startProgress)(f); reader.onprogress = (updateProgress)(f); reader.onerror = (errorProgress)(f); //reader.onload = (handleReadGeoJson)(f); reader.onload = (startWorker)(f); reader.onloadend = (updateLayerList)(f); // read the geojson reader.readAsText(f); } }; var handleDragOver = function(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. }; // Set events mapEl = document.getElementById("map"); mapEl.addEventListener('dragover', handleDragOver, false); mapEl.addEventListener('drop', handleDropGeojson, false); } else { alert('The File APIs are not fully supported in this browser.'); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,268 @@ .mapboxgl-map { font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif; overflow: hidden; position: relative; -webkit-tap-highlight-color: rgba(0,0,0,0); } .mapboxgl-canvas-container.mapboxgl-interactive, .mapboxgl-ctrl-nav-compass { cursor: -webkit-grab; cursor: -moz-grab; cursor: grab; } .mapboxgl-canvas-container.mapboxgl-interactive:active, .mapboxgl-ctrl-nav-compass:active { cursor: -webkit-grabbing; cursor: -moz-grabbing; cursor: grabbing; } .mapboxgl-ctrl-top-left, .mapboxgl-ctrl-top-right, .mapboxgl-ctrl-bottom-left, .mapboxgl-ctrl-bottom-right { position:absolute; pointer-events:none; z-index:2; } .mapboxgl-ctrl-top-left { top:0; left:0; } .mapboxgl-ctrl-top-right { top:0; right:0; } .mapboxgl-ctrl-bottom-left { bottom:0; left:0; } .mapboxgl-ctrl-bottom-right { right:0; bottom:0; } .mapboxgl-ctrl { clear:both; pointer-events:auto } .mapboxgl-ctrl-top-left .mapboxgl-ctrl { margin:10px 0 0 10px; float:left; } .mapboxgl-ctrl-top-right .mapboxgl-ctrl{ margin:10px 10px 0 0; float:right; } .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl { margin:0 0 10px 10px; float:left; } .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl { margin:0 10px 10px 0; float:right; } .mapboxgl-ctrl-group { border-radius: 4px; -moz-box-shadow: 0px 0px 2px rgba(0,0,0,0.1); -webkit-box-shadow: 0px 0px 2px rgba(0,0,0,0.1); box-shadow: 0px 0px 0px 2px rgba(0,0,0,0.1); overflow: hidden; background: #fff; } .mapboxgl-ctrl-group > button { width: 30px; height: 30px; display: block; padding: 0; outline: none; border: none; border-bottom: 1px solid #ddd; box-sizing: border-box; background-color: rgba(0,0,0,0); cursor: pointer; } /* https://bugzilla.mozilla.org/show_bug.cgi?id=140562 */ .mapboxgl-ctrl > button::-moz-focus-inner { border: 0; padding: 0; } .mapboxgl-ctrl > button:last-child { border-bottom: 0; } .mapboxgl-ctrl > button:hover { background-color: rgba(0,0,0,0.05); } .mapboxgl-ctrl-icon, .mapboxgl-ctrl-icon > div.arrow { speak: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-out { padding: 5px; background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23333333%3B%27%20d%3D%27m%207%2C9%20c%20-0.554%2C0%20-1%2C0.446%20-1%2C1%200%2C0.554%200.446%2C1%201%2C1%20l%206%2C0%20c%200.554%2C0%201%2C-0.446%201%2C-1%200%2C-0.554%20-0.446%2C-1%20-1%2C-1%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A"); } .mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-in { padding: 5px; background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23333333%3B%27%20d%3D%27M%2010%206%20C%209.446%206%209%206.4459904%209%207%20L%209%209%20L%207%209%20C%206.446%209%206%209.446%206%2010%20C%206%2010.554%206.446%2011%207%2011%20L%209%2011%20L%209%2013%20C%209%2013.55401%209.446%2014%2010%2014%20C%2010.554%2014%2011%2013.55401%2011%2013%20L%2011%2011%20L%2013%2011%20C%2013.554%2011%2014%2010.554%2014%2010%20C%2014%209.446%2013.554%209%2013%209%20L%2011%209%20L%2011%207%20C%2011%206.4459904%2010.554%206%2010%206%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A"); } .mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate { padding: 5px; background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCIgdmVyc2lvbj0iMS4xIj48cGF0aCBkPSJNMTAgNEM5IDQgOSA1IDkgNUw5IDUuMUE1IDUgMCAwIDAgNS4xIDlMNSA5QzUgOSA0IDkgNCAxMCA0IDExIDUgMTEgNSAxMUw1LjEgMTFBNSA1IDAgMCAwIDkgMTQuOUw5IDE1QzkgMTUgOSAxNiAxMCAxNiAxMSAxNiAxMSAxNSAxMSAxNUwxMSAxNC45QTUgNSAwIDAgMCAxNC45IDExTDE1IDExQzE1IDExIDE2IDExIDE2IDEwIDE2IDkgMTUgOSAxNSA5TDE0LjkgOUE1IDUgMCAwIDAgMTEgNS4xTDExIDVDMTEgNSAxMSA0IDEwIDR6TTEwIDYuNUEzLjUgMy41IDAgMCAxIDEzLjUgMTAgMy41IDMuNSAwIDAgMSAxMCAxMy41IDMuNSAzLjUgMCAwIDEgNi41IDEwIDMuNSAzLjUgMCAwIDEgMTAgNi41ek0xMCA4LjNBMS44IDEuOCAwIDAgMCA4LjMgMTAgMS44IDEuOCAwIDAgMCAxMCAxMS44IDEuOCAxLjggMCAwIDAgMTEuOCAxMCAxLjggMS44IDAgMCAwIDEwIDguM3oiIGZpbGw9IiMzMzMiLz48L3N2Zz4="); } .mapboxgl-ctrl-icon.mapboxgl-ctrl-compass > div.arrow { width: 20px; height: 20px; margin: 5px; background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%0A%09%3Cpolygon%20fill%3D%27%23333333%27%20points%3D%276%2C9%2010%2C1%2014%2C9%27%2F%3E%0A%09%3Cpolygon%20fill%3D%27%23CCCCCC%27%20points%3D%276%2C11%2010%2C19%2014%2C11%20%27%2F%3E%0A%3C%2Fsvg%3E"); background-repeat: no-repeat; } .mapboxgl-ctrl.mapboxgl-ctrl-attrib { padding: 0 5px; background-color: rgba(255,255,255,0.5); margin: 0; } .mapboxgl-ctrl-attrib a { color: rgba(0,0,0,0.75); text-decoration: none; } .mapboxgl-ctrl-attrib a:hover { color: inherit; text-decoration: underline; } .mapboxgl-ctrl-attrib .mapbox-improve-map { font-weight: bold; margin-left: 2px; } .mapboxgl-ctrl-scale { background-color: rgba(255,255,255,0.75); font-size: 10px; border-width: medium 2px 2px; border-style: none solid solid; border-color: #333; padding: 0 5px; color: #333; } .mapboxgl-popup { position: absolute; top: 0; left: 0; display: -webkit-flex; display: flex; will-change: transform; pointer-events: none; } .mapboxgl-popup-anchor-top, .mapboxgl-popup-anchor-top-left, .mapboxgl-popup-anchor-top-right { -webkit-flex-direction: column; flex-direction: column; } .mapboxgl-popup-anchor-bottom, .mapboxgl-popup-anchor-bottom-left, .mapboxgl-popup-anchor-bottom-right { -webkit-flex-direction: column-reverse; flex-direction: column-reverse; } .mapboxgl-popup-anchor-left { -webkit-flex-direction: row; flex-direction: row; } .mapboxgl-popup-anchor-right { -webkit-flex-direction: row-reverse; flex-direction: row-reverse; } .mapboxgl-popup-tip { width: 0; height: 0; border: 10px solid transparent; z-index: 1; } .mapboxgl-popup-anchor-top .mapboxgl-popup-tip { -webkit-align-self: center; align-self: center; border-top: none; border-bottom-color: #fff; } .mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip { -webkit-align-self: flex-start; align-self: flex-start; border-top: none; border-left: none; border-bottom-color: #fff; } .mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip { -webkit-align-self: flex-end; align-self: flex-end; border-top: none; border-right: none; border-bottom-color: #fff; } .mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip { -webkit-align-self: center; align-self: center; border-bottom: none; border-top-color: #fff; } .mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip { -webkit-align-self: flex-start; align-self: flex-start; border-bottom: none; border-left: none; border-top-color: #fff; } .mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip { -webkit-align-self: flex-end; align-self: flex-end; border-bottom: none; border-right: none; border-top-color: #fff; } .mapboxgl-popup-anchor-left .mapboxgl-popup-tip { -webkit-align-self: center; align-self: center; border-left: none; border-right-color: #fff; } .mapboxgl-popup-anchor-right .mapboxgl-popup-tip { -webkit-align-self: center; align-self: center; border-right: none; border-left-color: #fff; } .mapboxgl-popup-close-button { position: absolute; right: 0; top: 0; border: none; border-radius: 0 3px 0 0; cursor: pointer; background-color: rgba(0,0,0,0); } .mapboxgl-popup-close-button:hover { background-color: rgba(0,0,0,0.05); } .mapboxgl-popup-content { position: relative; background: #fff; border-radius: 3px; box-shadow: 0 1px 2px rgba(0,0,0,0.10); padding: 10px 10px 15px; pointer-events: auto; } .mapboxgl-popup-anchor-top-left .mapboxgl-popup-content { border-top-left-radius: 0; } .mapboxgl-popup-anchor-top-right .mapboxgl-popup-content { border-top-right-radius: 0; } .mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-content { border-bottom-left-radius: 0; } .mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-content { border-bottom-right-radius: 0; } .mapboxgl-marker { position: absolute; top: 0; left: 0; will-change: transform; } .mapboxgl-crosshair, .mapboxgl-crosshair .mapboxgl-interactive, .mapboxgl-crosshair .mapboxgl-interactive:active { cursor: crosshair; } .mapboxgl-boxzoom { position: absolute; top: 0; left: 0; width: 0; height: 0; background: #fff; border: 2px dotted #202020; opacity: 0.5; } @media print { .mapbox-improve-map { display:none; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,44 @@ body { margin:0; padding:0; } #map { position:absolute; top:0; bottom:0; width:100%; } .loading-screen { background-color : rgba(47,47,47,0.6); top: 0px; width: 100%; bottom:0px; display: block; position:absolute; } .loading-container { /*font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;*/ font-family : "Lucida Console", Monaco, monospace; color: #0f0; position:absolute; width: 40%; left: 50%; padding: 10px; } .loading-item { padding: 5px; width: 99%; } .loading-bar-out { height:5px; width:100%; border:1px solid #0f0; } .loading-bar-in { width:0px; height:100%; background-color: #0f0; } .loading-bar-txt { font-size: 14px; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,193 +4,14 @@ <meta charset='utf-8' /> <title></title> <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <meta http-equiv="cache-control" content="Public"> <link href='css/mapbox-gl.css' rel='stylesheet' /> <link href='css/style.css' rel='stylesheet' /> </head> <body> <div id='map'></div> <script src='js/mapbox-gl.js'></script> <script src='js/helpers.js'></script> <script src='js/app.js'></script> </body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,175 @@ // mapbox gl init mapboxgl.accessToken = 'pk.eyJ1IjoidW5lcGdyaWQiLCJhIjoiY2lzZnowenUwMDAzdjJubzZyZ3R1bjIzZyJ9.uyP-RWjY-94qCVajU0u8KA'; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v9', center: [15.6, -4.3], zoom: 10 }); var data = {}; // test if file api is available if (window.File && window.FileReader && window.FileList && window.Blob) { // handle read geojson // Update progress var updateProgress = function(theFile) { return function(e) { // evt is an ProgressEvent. 100/2 as loading is ~ half the process if (e.lengthComputable) { var percentLoaded = Math.round((e.loaded / e.total) * 50); progressScreen( true, theFile.name, percentLoaded, theFile.name + " loading (" + percentLoaded + "%)" ); } }; }; // init progress bar var startProgress = function(theFile) { return function(e) { progressScreen( true, theFile.name, 0, theFile.name + " init .. " ); }; }; // on error, set progress to 100 (remove it) var errorProgress = function(theFile) { return function(e) { progressScreen( true, theFile.name, 100, theFile.name + "stop .. " ); }; }; // handle worker var startWorker = function(theFile) { return function(e) { // Create a worker to handle this file var w = new Worker("js/handleReadJson.js"); // parse file content before passing to worker. var gJson = JSON.parse(e.target.result); // Message to pass to the worker var res = { json: gJson, fileName: theFile.name }; // handle message received w.onmessage = function(e) { var m = e.data; if ( m.progress ) { progressScreen( true, theFile.name, m.progress, theFile.name + ":" + m.message ); } // send alert for errors message if( m.errorMessage ){ alert(m.errorMessage); } // If extent is received if (m.extent) { map.fitBounds(m.extent); } // If layer is valid and returned if (m.layer) { try { progressScreen( true, theFile.name, 100, theFile.name + " done" ); // add source to map map.addSource(m.id, { "type": "geojson", "data": gJson }); // add layer map.addLayer(m.layer); // set progress to max data[m.id] = gJson; } catch(err){ alert(err); } // close worker w.terminate(); } }; // launch process w.postMessage(res); }; }; var updateLayerList = function(theFile) { return function(e) {}; }; // handle drop event var handleDropGeojson = function(evt) { evt.stopPropagation(); evt.preventDefault(); var files = evt.dataTransfer.files; var nFiles = files.length; var incFile = 100 / nFiles; var progressBar = 0; // In case of multiple file, loop on them for (var i = 0; i < nFiles; i++) { f = files[i]; // Only process geojson files. Validate later. if (f.name.indexOf(".geojson") == -1) { continue; } // get a new reader var reader = new FileReader(); // handle events reader.onloadstart = (startProgress)(f); reader.onprogress = (updateProgress)(f); reader.onerror = (errorProgress)(f); reader.onload = (startWorker)(f); reader.onloadend = (updateLayerList)(f); // read the geojson reader.readAsText(f); } }; var handleDragOver = function(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. }; // Set events mapEl = document.getElementById("map"); mapEl.addEventListener('dragover', handleDragOver, false); mapEl.addEventListener('drop', handleDropGeojson, false); } else { alert('The File APIs are not fully supported in this browser.'); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1566 @@ (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.geojsonhint = 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){ (function (process){ /* parser generated by jison 0.4.17 */ /* Returns a Parser object of the following structure: Parser: { yy: {} } Parser.prototype: { yy: {}, trace: function(), symbols_: {associative list: name ==> number}, terminals_: {associative list: number ==> name}, productions_: [...], performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), table: [...], defaultActions: {...}, parseError: function(str, hash), parse: function(input), lexer: { EOF: 1, parseError: function(str, hash), setInput: function(input), input: function(), unput: function(str), more: function(), less: function(n), pastInput: function(), upcomingInput: function(), showPosition: function(), test_match: function(regex_match_array, rule_index), next: function(), lex: function(), begin: function(condition), popState: function(), _currentRules: function(), topState: function(), pushState: function(condition), options: { ranges: boolean (optional: true ==> token location info will include a .range[] member) flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) }, performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), rules: [...], conditions: {associative list: name ==> set}, } } token location info (@$, _$, etc.): { first_line: n, last_line: n, first_column: n, last_column: n, range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) } the parseError function receives a 'hash' object with these members for lexer and parser errors: { text: (matched text) token: (the produced terminal token, if any) line: (yylineno) } while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { loc: (yylloc) expected: (string describing the set of expected tokens) recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) } */ var jsonlint = (function(){ var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,12],$V1=[1,13],$V2=[1,9],$V3=[1,10],$V4=[1,11],$V5=[1,14],$V6=[1,15],$V7=[14,18,22,24],$V8=[18,22],$V9=[22,24]; var parser = {trace: function trace() { }, yy: {}, symbols_: {"error":2,"JSONString":3,"STRING":4,"JSONNumber":5,"NUMBER":6,"JSONNullLiteral":7,"NULL":8,"JSONBooleanLiteral":9,"TRUE":10,"FALSE":11,"JSONText":12,"JSONValue":13,"EOF":14,"JSONObject":15,"JSONArray":16,"{":17,"}":18,"JSONMemberList":19,"JSONMember":20,":":21,",":22,"[":23,"]":24,"JSONElementList":25,"$accept":0,"$end":1}, terminals_: {2:"error",4:"STRING",6:"NUMBER",8:"NULL",10:"TRUE",11:"FALSE",14:"EOF",17:"{",18:"}",21:":",22:",",23:"[",24:"]"}, productions_: [0,[3,1],[5,1],[7,1],[9,1],[9,1],[12,2],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[15,2],[15,3],[20,3],[19,1],[19,3],[16,2],[16,3],[25,1],[25,3]], performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { /* this == yyval */ var $0 = $$.length - 1; switch (yystate) { case 1: // replace escaped characters with actual character this.$ = yytext.replace(/\\(\\|")/g, "$"+"1") .replace(/\\n/g,'\n') .replace(/\\r/g,'\r') .replace(/\\t/g,'\t') .replace(/\\v/g,'\v') .replace(/\\f/g,'\f') .replace(/\\b/g,'\b'); break; case 2: this.$ = Number(yytext); break; case 3: this.$ = null; break; case 4: this.$ = true; break; case 5: this.$ = false; break; case 6: return this.$ = $$[$0-1]; break; case 13: this.$ = {}; Object.defineProperty(this.$, '__line__', { value: this._$.first_line, enumerable: false }) break; case 14: case 19: this.$ = $$[$0-1]; Object.defineProperty(this.$, '__line__', { value: this._$.first_line, enumerable: false }) break; case 15: this.$ = [$$[$0-2], $$[$0]]; break; case 16: this.$ = {}; this.$[$$[$0][0]] = $$[$0][1]; break; case 17: this.$ = $$[$0-2]; if ($$[$0-2][$$[$0][0]] !== undefined) { if (!this.$.__duplicateProperties__) { Object.defineProperty(this.$, '__duplicateProperties__', { value: [], enumerable: false }); } this.$.__duplicateProperties__.push($$[$0][0]); } $$[$0-2][$$[$0][0]] = $$[$0][1]; break; case 18: this.$ = []; Object.defineProperty(this.$, '__line__', { value: this._$.first_line, enumerable: false }) break; case 20: this.$ = [$$[$0]]; break; case 21: this.$ = $$[$0-2]; $$[$0-2].push($$[$0]); break; } }, table: [{3:5,4:$V0,5:6,6:$V1,7:3,8:$V2,9:4,10:$V3,11:$V4,12:1,13:2,15:7,16:8,17:$V5,23:$V6},{1:[3]},{14:[1,16]},o($V7,[2,7]),o($V7,[2,8]),o($V7,[2,9]),o($V7,[2,10]),o($V7,[2,11]),o($V7,[2,12]),o($V7,[2,3]),o($V7,[2,4]),o($V7,[2,5]),o([14,18,21,22,24],[2,1]),o($V7,[2,2]),{3:20,4:$V0,18:[1,17],19:18,20:19},{3:5,4:$V0,5:6,6:$V1,7:3,8:$V2,9:4,10:$V3,11:$V4,13:23,15:7,16:8,17:$V5,23:$V6,24:[1,21],25:22},{1:[2,6]},o($V7,[2,13]),{18:[1,24],22:[1,25]},o($V8,[2,16]),{21:[1,26]},o($V7,[2,18]),{22:[1,28],24:[1,27]},o($V9,[2,20]),o($V7,[2,14]),{3:20,4:$V0,20:29},{3:5,4:$V0,5:6,6:$V1,7:3,8:$V2,9:4,10:$V3,11:$V4,13:30,15:7,16:8,17:$V5,23:$V6},o($V7,[2,19]),{3:5,4:$V0,5:6,6:$V1,7:3,8:$V2,9:4,10:$V3,11:$V4,13:31,15:7,16:8,17:$V5,23:$V6},o($V8,[2,17]),o($V8,[2,15]),o($V9,[2,21])], defaultActions: {16:[2,6]}, parseError: function parseError(str, hash) { if (hash.recoverable) { this.trace(str); } else { function _parseError (msg, hash) { this.message = msg; this.hash = hash; } _parseError.prototype = Error; throw new _parseError(str, hash); } }, parse: function parse(input) { var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; var args = lstack.slice.call(arguments, 1); var lexer = Object.create(this.lexer); var sharedState = { yy: {} }; for (var k in this.yy) { if (Object.prototype.hasOwnProperty.call(this.yy, k)) { sharedState.yy[k] = this.yy[k]; } } lexer.setInput(input, sharedState.yy); sharedState.yy.lexer = lexer; sharedState.yy.parser = this; if (typeof lexer.yylloc == 'undefined') { lexer.yylloc = {}; } var yyloc = lexer.yylloc; lstack.push(yyloc); var ranges = lexer.options && lexer.options.ranges; if (typeof sharedState.yy.parseError === 'function') { this.parseError = sharedState.yy.parseError; } else { this.parseError = Object.getPrototypeOf(this).parseError; } function popStack(n) { stack.length = stack.length - 2 * n; vstack.length = vstack.length - n; lstack.length = lstack.length - n; } _token_stack: var lex = function () { var token; token = lexer.lex() || EOF; if (typeof token !== 'number') { token = self.symbols_[token] || token; } return token; }; var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; while (true) { state = stack[stack.length - 1]; if (this.defaultActions[state]) { action = this.defaultActions[state]; } else { if (symbol === null || typeof symbol == 'undefined') { symbol = lex(); } action = table[state] && table[state][symbol]; } if (typeof action === 'undefined' || !action.length || !action[0]) { var errStr = ''; expected = []; for (p in table[state]) { if (this.terminals_[p] && p > TERROR) { expected.push('\'' + this.terminals_[p] + '\''); } } if (lexer.showPosition) { errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; } else { errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); } this.parseError(errStr, { text: lexer.match, token: this.terminals_[symbol] || symbol, line: lexer.yylineno, loc: yyloc, expected: expected }); } if (action[0] instanceof Array && action.length > 1) { throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); } switch (action[0]) { case 1: stack.push(symbol); vstack.push(lexer.yytext); lstack.push(lexer.yylloc); stack.push(action[1]); symbol = null; if (!preErrorSymbol) { yyleng = lexer.yyleng; yytext = lexer.yytext; yylineno = lexer.yylineno; yyloc = lexer.yylloc; if (recovering > 0) { recovering--; } } else { symbol = preErrorSymbol; preErrorSymbol = null; } break; case 2: len = this.productions_[action[1]][1]; yyval.$ = vstack[vstack.length - len]; yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column }; if (ranges) { yyval._$.range = [ lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1] ]; } r = this.performAction.apply(yyval, [ yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack ].concat(args)); if (typeof r !== 'undefined') { return r; } if (len) { stack = stack.slice(0, -1 * len * 2); vstack = vstack.slice(0, -1 * len); lstack = lstack.slice(0, -1 * len); } stack.push(this.productions_[action[1]][0]); vstack.push(yyval.$); lstack.push(yyval._$); newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; stack.push(newState); break; case 3: return true; } } return true; }}; /* generated by jison-lex 0.3.4 */ var lexer = (function(){ var lexer = ({ EOF:1, parseError:function parseError(str, hash) { if (this.yy.parser) { this.yy.parser.parseError(str, hash); } else { throw new Error(str); } }, // resets the lexer, sets new input setInput:function (input, yy) { this.yy = yy || this.yy || {}; this._input = input; this._more = this._backtrack = this.done = false; this.yylineno = this.yyleng = 0; this.yytext = this.matched = this.match = ''; this.conditionStack = ['INITIAL']; this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 }; if (this.options.ranges) { this.yylloc.range = [0,0]; } this.offset = 0; return this; }, // consumes and returns one char from the input input:function () { var ch = this._input[0]; this.yytext += ch; this.yyleng++; this.offset++; this.match += ch; this.matched += ch; var lines = ch.match(/(?:\r\n?|\n).*/g); if (lines) { this.yylineno++; this.yylloc.last_line++; } else { this.yylloc.last_column++; } if (this.options.ranges) { this.yylloc.range[1]++; } this._input = this._input.slice(1); return ch; }, // unshifts one char (or a string) into the input unput:function (ch) { var len = ch.length; var lines = ch.split(/(?:\r\n?|\n)/g); this._input = ch + this._input; this.yytext = this.yytext.substr(0, this.yytext.length - len); //this.yyleng -= len; this.offset -= len; var oldLines = this.match.split(/(?:\r\n?|\n)/g); this.match = this.match.substr(0, this.match.length - 1); this.matched = this.matched.substr(0, this.matched.length - 1); if (lines.length - 1) { this.yylineno -= lines.length - 1; } var r = this.yylloc.range; this.yylloc = { first_line: this.yylloc.first_line, last_line: this.yylineno + 1, first_column: this.yylloc.first_column, last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len }; if (this.options.ranges) { this.yylloc.range = [r[0], r[0] + this.yyleng - len]; } this.yyleng = this.yytext.length; return this; }, // When called from action, caches matched text and appends it on next action more:function () { this._more = true; return this; }, // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. reject:function () { if (this.options.backtrack_lexer) { this._backtrack = true; } else { return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { text: "", token: null, line: this.yylineno }); } return this; }, // retain first n characters of the match less:function (n) { this.unput(this.match.slice(n)); }, // displays already matched input, i.e. for error messages pastInput:function () { var past = this.matched.substr(0, this.matched.length - this.match.length); return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); }, // displays upcoming input, i.e. for error messages upcomingInput:function () { var next = this.match; if (next.length < 20) { next += this._input.substr(0, 20-next.length); } return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); }, // displays the character position where the lexing error occurred, i.e. for error messages showPosition:function () { var pre = this.pastInput(); var c = new Array(pre.length + 1).join("-"); return pre + this.upcomingInput() + "\n" + c + "^"; }, // test the lexed token: return FALSE when not a match, otherwise return token test_match:function (match, indexed_rule) { var token, lines, backup; if (this.options.backtrack_lexer) { // save context backup = { yylineno: this.yylineno, yylloc: { first_line: this.yylloc.first_line, last_line: this.last_line, first_column: this.yylloc.first_column, last_column: this.yylloc.last_column }, yytext: this.yytext, match: this.match, matches: this.matches, matched: this.matched, yyleng: this.yyleng, offset: this.offset, _more: this._more, _input: this._input, yy: this.yy, conditionStack: this.conditionStack.slice(0), done: this.done }; if (this.options.ranges) { backup.yylloc.range = this.yylloc.range.slice(0); } } lines = match[0].match(/(?:\r\n?|\n).*/g); if (lines) { this.yylineno += lines.length; } this.yylloc = { first_line: this.yylloc.last_line, last_line: this.yylineno + 1, first_column: this.yylloc.last_column, last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length }; this.yytext += match[0]; this.match += match[0]; this.matches = match; this.yyleng = this.yytext.length; if (this.options.ranges) { this.yylloc.range = [this.offset, this.offset += this.yyleng]; } this._more = false; this._backtrack = false; this._input = this._input.slice(match[0].length); this.matched += match[0]; token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); if (this.done && this._input) { this.done = false; } if (token) { return token; } else if (this._backtrack) { // recover context for (var k in backup) { this[k] = backup[k]; } return false; // rule action called reject() implying the next rule should be tested instead. } return false; }, // return next match in input next:function () { if (this.done) { return this.EOF; } if (!this._input) { this.done = true; } var token, match, tempMatch, index; if (!this._more) { this.yytext = ''; this.match = ''; } var rules = this._currentRules(); for (var i = 0; i < rules.length; i++) { tempMatch = this._input.match(this.rules[rules[i]]); if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { match = tempMatch; index = i; if (this.options.backtrack_lexer) { token = this.test_match(tempMatch, rules[i]); if (token !== false) { return token; } else if (this._backtrack) { match = false; continue; // rule action called reject() implying a rule MISmatch. } else { // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) return false; } } else if (!this.options.flex) { break; } } } if (match) { token = this.test_match(match, rules[index]); if (token !== false) { return token; } // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) return false; } if (this._input === "") { return this.EOF; } else { return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: "", token: null, line: this.yylineno }); } }, // return next match that has a token lex:function lex() { var r = this.next(); if (r) { return r; } else { return this.lex(); } }, // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) begin:function begin(condition) { this.conditionStack.push(condition); }, // pop the previously active lexer condition state off the condition stack popState:function popState() { var n = this.conditionStack.length - 1; if (n > 0) { return this.conditionStack.pop(); } else { return this.conditionStack[0]; } }, // produce the lexer rule set which is active for the currently active lexer condition state _currentRules:function _currentRules() { if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; } else { return this.conditions["INITIAL"].rules; } }, // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available topState:function topState(n) { n = this.conditionStack.length - 1 - Math.abs(n || 0); if (n >= 0) { return this.conditionStack[n]; } else { return "INITIAL"; } }, // alias for begin(condition) pushState:function pushState(condition) { this.begin(condition); }, // return the number of states currently on the stack stateStackSize:function stateStackSize() { return this.conditionStack.length; }, options: {}, performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { var YYSTATE=YY_START; switch($avoiding_name_collisions) { case 0:/* skip whitespace */ break; case 1:return 6 break; case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4 break; case 3:return 17 break; case 4:return 18 break; case 5:return 23 break; case 6:return 24 break; case 7:return 22 break; case 8:return 21 break; case 9:return 10 break; case 10:return 11 break; case 11:return 8 break; case 12:return 14 break; case 13:return 'INVALID' break; } }, rules: [/^(?:\s+)/,/^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/,/^(?:"(?:\\[\\"bfnrt\/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/,/^(?:\{)/,/^(?:\})/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?::)/,/^(?:true\b)/,/^(?:false\b)/,/^(?:null\b)/,/^(?:$)/,/^(?:.)/], conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}} }); return lexer; })(); parser.lexer = lexer; function Parser () { this.yy = {}; } Parser.prototype = parser;parser.Parser = Parser; return new Parser; })(); if (typeof require !== 'undefined' && typeof exports !== 'undefined') { exports.parser = jsonlint; exports.Parser = jsonlint.Parser; exports.parse = function () { return jsonlint.parse.apply(jsonlint, arguments); }; exports.main = function commonjsMain(args) { if (!args[1]) { console.log('Usage: '+args[0]+' FILE'); process.exit(1); } var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8"); return exports.parser.parse(source); }; if (typeof module !== 'undefined' && require.main === module) { exports.main(process.argv.slice(1)); } } }).call(this,require('_process')) },{"_process":6,"fs":4,"path":5}],2:[function(require,module,exports){ /** * @alias geojsonhint * @param {(string|object)} GeoJSON given as a string or as an object * @param {Object} options * @param {boolean} [options.noDuplicateMembers=true] forbid repeated * properties. This is only available for string input, becaused parsed * Objects cannot have duplicate properties. * @returns {Array<Object>} an array of errors */ function hint(gj, options) { var errors = []; var precisionWarningCount = 0; function root(_) { if ((!options || options.noDuplicateMembers !== false) && _.__duplicateProperties__) { errors.push({ message: 'An object contained duplicate members, making parsing ambigous: ' + _.__duplicateProperties__.join(', '), line: _.__line__ }); } if (!_.type) { errors.push({ message: 'The type property is required and was not found', line: _.__line__ }); } else if (!types[_.type]) { var expectedType = typesLower[_.type.toLowerCase()]; if (expectedType !== undefined) { errors.push({ message: 'Expected ' + expectedType + ' but got ' + _.type + ' (case sensitive)', line: _.__line__ }); } else { errors.push({ message: 'The type ' + _.type + ' is unknown', line: _.__line__ }); } } else if (_) { types[_.type](_); } } function everyIs(_, type) { // make a single exception because typeof null === 'object' return _.every(function(x) { return (x !== null) && (typeof x === type); }); } function requiredProperty(_, name, type) { if (typeof _[name] === 'undefined') { return errors.push({ message: '"' + name + '" property required', line: _.__line__ }); } else if (type === 'array') { if (!Array.isArray(_[name])) { return errors.push({ message: '"' + name + '" property should be an array, but is an ' + (typeof _[name]) + ' instead', line: _.__line__ }); } } else if (type && typeof _[name] !== type) { return errors.push({ message: '"' + name + '" property should be ' + (type) + ', but is an ' + (typeof _[name]) + ' instead', line: _.__line__ }); } } // http://geojson.org/geojson-spec.html#feature-collection-objects function FeatureCollection(featureCollection) { crs(featureCollection); bbox(featureCollection); if (featureCollection.properties !== undefined) { errors.push({ message: 'FeatureCollection object cannot contain a "properties" member', line: featureCollection.__line__ }); } if (featureCollection.coordinates !== undefined) { errors.push({ message: 'FeatureCollection object cannot contain a "coordinates" member', line: featureCollection.__line__ }); } if (!requiredProperty(featureCollection, 'features', 'array')) { if (!everyIs(featureCollection.features, 'object')) { return errors.push({ message: 'Every feature must be an object', line: featureCollection.__line__ }); } featureCollection.features.forEach(Feature); } } // http://geojson.org/geojson-spec.html#positions function position(_, line) { if (!Array.isArray(_)) { return errors.push({ message: 'position should be an array, is a ' + (typeof _) + ' instead', line: _.__line__ || line }); } else { if (_.length < 2) { return errors.push({ message: 'position must have 2 or more elements', line: _.__line__ || line }); } if (_.length > 3) { return errors.push({ message: 'position should not have more than 3 elements', line: _.__line__ || line }); } if (!everyIs(_, 'number')) { return errors.push({ message: 'each element in a position must be a number', line: _.__line__ || line }); } var maxPrecisionWarnings = 10; var maxPrecision = 6; var num; if (precisionWarningCount == maxPrecisionWarnings) { precisionWarningCount += 1; return errors.push({ message: "truncated warnings: we've encountered coordinate precision warning " + maxPrecisionWarnings + " times, no more warnings will be reported", level: "warn", line: _.__line__ || line }); } else if (precisionWarningCount < maxPrecisionWarnings) { _.forEach(function(num) { // TODO there has got to be a better way. Check original text? // By this point number has already been parsed to a float... var precision = 0; var decimalStr = (num + "").split(".")[1]; if (decimalStr !== undefined) precision = decimalStr.length; if (precision > maxPrecision) { precisionWarningCount += 1; return errors.push({ message: "precision of coordinates should be reduced", level: "warn", line: _.__line__ || line }); } }); } } } function positionArray(coords, type, depth, line) { if (line === undefined && coords.__line__ !== undefined) { line = coords.__line__; } if (depth === 0) { return position(coords, line); } else { if (depth === 1 && type) { if (type === 'LinearRing') { if (!Array.isArray(coords[coords.length - 1])) { errors.push({ message: 'a number was found where a coordinate array should have been found: this needs to be nested more deeply', line: line }); return true; } if (coords.length < 4) { errors.push({ message: 'a LinearRing of coordinates needs to have four or more positions', line: line }); } if (coords.length && (coords[coords.length - 1].length !== coords[0].length || !coords[coords.length - 1].every(function(position, index) { return coords[0][index] === position; }))) { errors.push({ message: 'the first and last positions in a LinearRing of coordinates must be the same', line: line }); } } else if (type === 'Line' && coords.length < 2) { return errors.push({ message: 'a line needs to have two or more coordinates to be valid', line: line }); } } if (!Array.isArray(coords)) { errors.push({ message: 'a number was found where a coordinate array should have been found: this needs to be nested more deeply', line: line }); } else { coords.forEach(function(c) { positionArray(c, type, depth - 1, c.__line__ || line); }); } } } function rightHandRule (geometry) { var rhr = true; if (geometry.type == 'Polygon') { rhr = isPolyRHR(geometry.coordinates); } else if (geometry.type == 'MultiPolygon') { if (!geometry.coordinates.every(isPolyRHR)) rhr = false; } if (!rhr) { errors.push({ message: 'Polygons and MultiPolygons should follow the right-hand rule', level: 'warn', line: geometry.__line__ }); } } function isPolyRHR (coords) { if (coords && coords.length > 0) { if (!isRingClockwise(coords[0])) return false; var interiorCoords = coords.slice(1, coords.length); if (interiorCoords.some(isRingClockwise)) return false; } return true; } function isRingClockwise (coords) { var area = 0; if (coords.length > 2) { var p1, p2; for (var i = 0; i < coords.length - 1; i++) { p1 = coords[i]; p2 = coords[i + 1]; area += rad(p2[0] - p1[0]) * (2 + Math.sin(rad(p1[1])) + Math.sin(rad(p2[1]))); } } return area >= 0; } function rad(x) { return x * Math.PI / 180; } function crs(_) { if (!_.crs) return; var defaultCRSName = "urn:ogc:def:crs:OGC:1.3:CRS84"; if (typeof _.crs === 'object' && _.crs.properties && _.crs.properties.name === defaultCRSName) { errors.push({ message: "old-style crs member is not recommended, this object is equivalent to the default and should be removed", level: "warn", line: _.__line__ }); } else { errors.push({ message: "old-style crs member is not recommended", level: "warn", line: _.__line__ }); } } function bbox(_) { if (!_.bbox) { return; } if (Array.isArray(_.bbox)) { if (!everyIs(_.bbox, 'number')) { errors.push({ message: 'each element in a bbox property must be a number', line: _.bbox.__line__ }); } if (!(_.bbox.length == 4 || _.bbox.length == 6)) { errors.push({ message: 'bbox must contain 4 elements (for 2D) or 6 elements (for 3D)', line: _.bbox.__line__ }); } return errors.length; } else { errors.push({ message: 'bbox property must be an array of numbers, but is a ' + (typeof _.bbox), line: _.__line__ }); } } function geometrySemantics(geom) { if (geom.properties !== undefined) { errors.push({ message: 'geometry object cannot contain a "properties" member', line: geom.__line__ }); } if (geom.geometry !== undefined) { errors.push({ message: 'geometry object cannot contain a "geometry" member', line: geom.__line__ }); } if (geom.features !== undefined) { errors.push({ message: 'geometry object cannot contain a "features" member', line: geom.__line__ }); } } // http://geojson.org/geojson-spec.html#point function Point(point) { crs(point); bbox(point); geometrySemantics(point); if (!requiredProperty(point, 'coordinates', 'array')) { position(point.coordinates); } } // http://geojson.org/geojson-spec.html#polygon function Polygon(polygon) { crs(polygon); bbox(polygon); if (!requiredProperty(polygon, 'coordinates', 'array')) { if (!positionArray(polygon.coordinates, 'LinearRing', 2)) { rightHandRule(polygon); } } } // http://geojson.org/geojson-spec.html#multipolygon function MultiPolygon(multiPolygon) { crs(multiPolygon); bbox(multiPolygon); if (!requiredProperty(multiPolygon, 'coordinates', 'array')) { if (!positionArray(multiPolygon.coordinates, 'LinearRing', 3)) { rightHandRule(multiPolygon); } } } // http://geojson.org/geojson-spec.html#linestring function LineString(lineString) { crs(lineString); bbox(lineString); if (!requiredProperty(lineString, 'coordinates', 'array')) { positionArray(lineString.coordinates, 'Line', 1); } } // http://geojson.org/geojson-spec.html#multilinestring function MultiLineString(multiLineString) { crs(multiLineString); bbox(multiLineString); if (!requiredProperty(multiLineString, 'coordinates', 'array')) { positionArray(multiLineString.coordinates, 'Line', 2); } } // http://geojson.org/geojson-spec.html#multipoint function MultiPoint(multiPoint) { crs(multiPoint); bbox(multiPoint); if (!requiredProperty(multiPoint, 'coordinates', 'array')) { positionArray(multiPoint.coordinates, '', 1); } } function GeometryCollection(geometryCollection) { crs(geometryCollection); bbox(geometryCollection); if (!requiredProperty(geometryCollection, 'geometries', 'array')) { if (!everyIs(geometryCollection.geometries, 'object')) { errors.push({ message: 'The geometries array in a GeometryCollection must contain only geometry objects', line: geometryCollection.__line__ }); } if (geometryCollection.geometries.length == 1) { errors.push({ message: 'GeometryCollection with a single geometry should be avoided in favor of single part or a single object of multi-part type', level: 'warn', line: geometryCollection.geometries.__line__ }); } geometryCollection.geometries.forEach(function(geometry) { if (geometry) { if (geometry.type === "GeometryCollection") { errors.push({ message: "GeometryCollection should avoid nested geometry collections", level: 'warn', line: geometryCollection.geometries.__line__ }); } root(geometry); } }); } } function Feature(feature) { crs(feature); bbox(feature); // https://github.com/geojson/draft-geojson/blob/master/middle.mkd#feature-object if (feature.id !== undefined && typeof feature.id !== 'string' && typeof feature.id !== 'number') { errors.push({ message: 'Feature "id" property must have a string or number value', line: feature.__line__ }); } if (feature.features !== undefined) { errors.push({ message: 'Feature object cannot contain a "features" member', line: feature.__line__ }); } if (feature.coordinates !== undefined) { errors.push({ message: 'Feature object cannot contain a "coordinates" member', line: feature.__line__ }); } if (feature.type !== 'Feature') { errors.push({ message: 'GeoJSON features must have a type=feature property', line: feature.__line__ }); } requiredProperty(feature, 'properties', 'object'); if (!requiredProperty(feature, 'geometry', 'object')) { // http://geojson.org/geojson-spec.html#feature-objects // tolerate null geometry if (feature.geometry) root(feature.geometry); } } var types = { Point: Point, Feature: Feature, MultiPoint: MultiPoint, LineString: LineString, MultiLineString: MultiLineString, FeatureCollection: FeatureCollection, GeometryCollection: GeometryCollection, Polygon: Polygon, MultiPolygon: MultiPolygon }; var typesLower = Object.keys(types).reduce(function(prev, curr) { prev[curr.toLowerCase()] = curr; return prev; }, {}); if (typeof gj !== 'object' || gj === null || gj === undefined) { errors.push({ message: 'The root of a GeoJSON object must be an object.', line: 0 }); return errors; } root(gj); errors.forEach(function(err) { if (err.hasOwnProperty('line') && err.line === undefined) { delete err.line; } }); return errors; } module.exports.hint = hint; },{}],3:[function(require,module,exports){ var jsonlint = require('jsonlint-lines'), geojsonHintObject = require('./object'); /** * @alias geojsonhint * @param {(string|object)} GeoJSON given as a string or as an object * @param {Object} options * @param {boolean} [options.noDuplicateMembers=true] forbid repeated * properties. This is only available for string input, becaused parsed * Objects cannot have duplicate properties. * @returns {Array<Object>} an array of errors */ function hint(str, options) { var gj, errors = []; if (typeof str === 'object') { gj = str; } else if (typeof str === 'string') { try { gj = jsonlint.parse(str); } catch(e) { var match = e.message.match(/line (\d+)/); var lineNumber = parseInt(match[1], 10); return [{ line: lineNumber - 1, message: e.message, error: e }]; } } else { return [{ message: 'Expected string or object as input', line: 0 }]; } errors = errors.concat(geojsonHintObject.hint(gj, options)); return errors; } module.exports.hint = hint; },{"./object":2,"jsonlint-lines":1}],4:[function(require,module,exports){ },{}],5:[function(require,module,exports){ (function (process){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // resolves . and .. elements in a path array with directory names there // must be no slashes, empty elements, or device names (c:\) in the array // (so also no leading and trailing slashes - it does not distinguish // relative and absolute paths) function normalizeArray(parts, allowAboveRoot) { // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = parts.length - 1; i >= 0; i--) { var last = parts[i]; if (last === '.') { parts.splice(i, 1); } else if (last === '..') { parts.splice(i, 1); up++; } else if (up) { parts.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (allowAboveRoot) { for (; up--; up) { parts.unshift('..'); } } return parts; } // Split a filename into [root, dir, basename, ext], unix version // 'root' is just a slash, or nothing. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; var splitPath = function(filename) { return splitPathRe.exec(filename).slice(1); }; // path.resolve([from ...], to) // posix version exports.resolve = function() { var resolvedPath = '', resolvedAbsolute = false; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { var path = (i >= 0) ? arguments[i] : process.cwd(); // Skip empty and invalid entries if (typeof path !== 'string') { throw new TypeError('Arguments to path.resolve must be strings'); } else if (!path) { continue; } resolvedPath = path + '/' + resolvedPath; resolvedAbsolute = path.charAt(0) === '/'; } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { return !!p; }), !resolvedAbsolute).join('/'); return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; }; // path.normalize(path) // posix version exports.normalize = function(path) { var isAbsolute = exports.isAbsolute(path), trailingSlash = substr(path, -1) === '/'; // Normalize the path path = normalizeArray(filter(path.split('/'), function(p) { return !!p; }), !isAbsolute).join('/'); if (!path && !isAbsolute) { path = '.'; } if (path && trailingSlash) { path += '/'; } return (isAbsolute ? '/' : '') + path; }; // posix version exports.isAbsolute = function(path) { return path.charAt(0) === '/'; }; // posix version exports.join = function() { var paths = Array.prototype.slice.call(arguments, 0); return exports.normalize(filter(paths, function(p, index) { if (typeof p !== 'string') { throw new TypeError('Arguments to path.join must be strings'); } return p; }).join('/')); }; // path.relative(from, to) // posix version exports.relative = function(from, to) { from = exports.resolve(from).substr(1); to = exports.resolve(to).substr(1); function trim(arr) { var start = 0; for (; start < arr.length; start++) { if (arr[start] !== '') break; } var end = arr.length - 1; for (; end >= 0; end--) { if (arr[end] !== '') break; } if (start > end) return []; return arr.slice(start, end - start + 1); } var fromParts = trim(from.split('/')); var toParts = trim(to.split('/')); var length = Math.min(fromParts.length, toParts.length); var samePartsLength = length; for (var i = 0; i < length; i++) { if (fromParts[i] !== toParts[i]) { samePartsLength = i; break; } } var outputParts = []; for (var i = samePartsLength; i < fromParts.length; i++) { outputParts.push('..'); } outputParts = outputParts.concat(toParts.slice(samePartsLength)); return outputParts.join('/'); }; exports.sep = '/'; exports.delimiter = ':'; exports.dirname = function(path) { var result = splitPath(path), root = result[0], dir = result[1]; if (!root && !dir) { // No dirname whatsoever return '.'; } if (dir) { // It has a dirname, strip trailing slash dir = dir.substr(0, dir.length - 1); } return root + dir; }; exports.basename = function(path, ext) { var f = splitPath(path)[2]; // TODO: make this comparison case-insensitive on windows? if (ext && f.substr(-1 * ext.length) === ext) { f = f.substr(0, f.length - ext.length); } return f; }; exports.extname = function(path) { return splitPath(path)[3]; }; function filter (xs, f) { if (xs.filter) return xs.filter(f); var res = []; for (var i = 0; i < xs.length; i++) { if (f(xs[i], i, xs)) res.push(xs[i]); } return res; } // String.prototype.substr - negative index don't work in IE8 var substr = 'ab'.substr(-1) === 'b' ? function (str, start, len) { return str.substr(start, len) } : function (str, start, len) { if (start < 0) start = str.length + start; return str.substr(start, len); } ; }).call(this,require('_process')) },{"_process":6}],6:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = setTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; clearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { setTimeout(drainQueue, 0); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}]},{},[3])(3) }); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,239 @@ // Importation of helpers importScripts( "https://npmcdn.com/geojsonhint@latest/geojsonhint.js", "turf_bbox.js", "helpers.js" ); // Inital message postMessage({ progress: 0, message: "start" }); // handle message send from the main thread onmessage = function(e) { try { /** * Initialisation : set local helper and variables */ // init variables var errorMsg = ""; var warningMsg = ""; var dat = e.data; var gJson = dat.json; var fileName = dat.fileName; // set basic timing function timerVal = 0; // start timer var timerStart = function() { timerVal = new Date(); }; // give intermediate time, reset timer var timerLap = function() { var lap = new Date() - timerVal; timerStart(); return lap; }; // printable version of timerLaè var timerLapString = function() { return " " + timerLap() + " ms "; }; // start timer timerStart(); /** * validation : geojson validation with geojsonhint */ // Validation. Is that a valid geojson ? var messages = geojsonhint.hint(gJson); // extract errors var errors = messages.filter(function(x){ return x.level == "error"; }); // extract message var warnings = messages.filter(function(x){ return x.level == "message"; }); // set a message with summary var logMessage = " geojson validation " + " n errors=" + errors.length + " n warnings =" + warnings.length + " done in" + timerLapString(); console.log(fileName + ":" + logMessage); // send message postMessage({ progress: 60, message: logMessage }); // validation : warnings if (warnings.length > 0) { warningMsg = warnings.length + " warning message(s) found. Check the console for more info"; postMessage({ progress: 75, msssage: warningMsg }); warnings.forEach(function(x) { console.log({file:fileName,warnings:x}); }); } // varlidation: errors if (errors.length > 0) { errorMsg = errors.length + " errors found. check the console for more info"; postMessage({ progress: 100, msssage: errorMsg, errorMessage: errorMsg }); errors.forEach(function(x) { console.log({file:fileName,errors:x}); }); return; } /** * Get extent : get extent using a Turf bbox */ var extent = turf.bbox(gJson); // Quick extent validation if ( extent[0] > 180 || extent[0] < -180 || extent[1] > 89 || extent[1] < -89 || extent[2] > 180 || extent[2] < -180 || extent[3] > 89 || extent[3] < -89 ) { errorMsg = fileName + " : extent seems to be out of range: " + extent; postMessage({ progress: 100, msssage: errorMsg, errorMessage: errorMsg }); console.log({ "errors": errorMsg }); return; } postMessage({ progress: 80, message: " extent found in " + timerLapString() }); /** * Avoid multi type : we don't handle them for now */ // array of types in data var geomTypes = gJson.features .map(function(x){ return x.geometry.type; }) .filter(function(v,i,s){ return s.indexOf(v) === i; }); postMessage({ progress: 90, message: " geom types =" + geomTypes + " found in " + timerLapString() }); // if more than one type, return an error if ( geomTypes.length>1) { var msg = "Multi geometry not yet implemented"; postMessage({ progress: 100, msssage: msg, errorMessage: fileName + ": " + msg }); console.log({ "errors": fileName + ": " + msg + ".(" + geomTypes + ")" }); return; } /** * Set default for a new layer */ // Set random id for source and layer var id = "mgl_drop_" + randomString(5) + "_" + fileName ; // Set random color var ran = Math.random(); var colA = randomHsl(0.6, ran); var colB = randomHsl(0.8, ran); // Set default type from geojson type var typ = typeSwitcher[geomTypes[0]]; // Set up default style var dummyStyle = { "circle": { "id": id, "source": id, "type": typ, "paint": { "circle-color": colA } }, "fill": { "id": id, "source": id, "type": typ, "paint": { "fill-color": colA, "fill-outline-color": colB } }, "line": { "id": id, "source": id, "type": typ, "paint": { "line-color": colA, "line-width": 10 } } }; postMessage({ progress: 99, message: "Add layer", id: id, extent: extent, layer: dummyStyle[typ] }); } catch(err) { postMessage({ progress: 100, errorMessage : err }); } }; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,132 @@ /** * Generate a random string of the given length * @param {integer} n Number of character * @return {string} random string */ var randomString = function(n) { var result = ""; if (!n) n = 5; var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < n; i++) result += characters.charAt(Math.floor(Math.random() * characters.length)); return result; }; /** * Generate a random hsla color string, with fixed saturation and lightness * @param {number} opacity opacity from 0 to 1 * @param {number} random value from 0 to 1 * @param {number} saturation from 0 to 100 * @param {number} lightness from 0 to 100 */ var randomHsl = function(opacity, random, saturation, lightness) { if (!opacity) opacity = 1; if (!saturation) saturation = 100; if (!lightness) lightness = 50; if (!random) random = Math.random(); res = "hsla(" + (random * 360) + ", " + saturation + "% " + ", " + lightness + "% " + ", " + opacity + ")"; return res; }; /** * Remove multiple layers by prefix * @param {object} map Map object * @param {string} prefix Prefix to search for in layers, if something found, remove it * @return {array} List of removed layer */ var removeLayersByPrefix = function(map, prefix) { var result = []; if (map) { // no method to get all layers ? var layers = map.style._layers; for (var l in layers) { if (l.indexOf(prefix) > -1) { map.removeLayer(l); result.push(l); } } } return result; }; /** * Create and manage multiple progression bar * @param {boolean} enable Enable the screen * @param {string} id Identifier of the given item * @param {number} percent Progress bar percentage * @param {string} text Optional text */ var progressScreen = function(enable, id, percent, text ) { lScreen = document.getElementsByClassName("loading-screen")[0]; if (!enable) { if (lScreen) lScreen.remove(); return; } if (!id || !percent || !text) return; if (!lScreen && enable) { lBody = document.getElementsByTagName("body")[0]; lScreen = document.createElement("div"); lScreen.className = "loading-screen"; lScreenContainer = document.createElement("div"); lScreenContainer.className = "loading-container"; lScreen.appendChild(lScreenContainer); lBody.appendChild(lScreen); } lItem = document.getElementById(id); if (!lItem) { lItem = document.createElement("div"); lItem.className = "loading-item"; lItem.setAttribute("id", id); pBarIn = document.createElement("div"); pBarIn.className = "loading-bar-in"; pBarOut = document.createElement("div"); pBarOut.className = "loading-bar-out"; pBarTxt = document.createElement("div"); pBarTxt.className = "loading-bar-txt"; pBarOut.appendChild(pBarIn); lItem.appendChild(pBarTxt); lItem.appendChild(pBarOut); lScreenContainer.appendChild(lItem); } else { pBarIn = lItem.getElementsByClassName("loading-bar-in")[0]; pBarTxt = lItem.getElementsByClassName("loading-bar-txt")[0]; } if (percent >= 100) { lItem = document.getElementById(id); if (lItem) lItem.remove(); } else { pBarIn.style.width = percent + "%"; pBarTxt.innerHTML = text; } lItems = lScreenContainer.getElementsByClassName("loading-item"); if (lItems.length === 0) progressScreen(false); }; // geojson type to mapbox gl type var typeSwitcher = { "Point": "circle", "MultiPoint": "line", "LineString": "line", "MultiLineString": "line", "Polygon": "fill", "MultiPolygon": "fill", "GeometryCollection": "fill" }; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,8 @@ (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.turf = 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 each=require("turf-meta").coordEach;module.exports=function(r){var e=[1/0,1/0,-(1/0),-(1/0)];return each(r,function(r){e[0]>r[0]&&(e[0]=r[0]),e[1]>r[1]&&(e[1]=r[1]),e[2]<r[0]&&(e[2]=r[0]),e[3]<r[1]&&(e[3]=r[1])}),e}; },{"turf-meta":2}],2:[function(require,module,exports){ function coordEach(e,o,t){var r,n,c,u,l,p,a,i,f,h,d=0,s="FeatureCollection"===e.type,y="Feature"===e.type,g=s?e.features.length:1;for(r=0;r<g;r++)for(f=s?e.features[r].geometry:y?e.geometry:e,h="GeometryCollection"===f.type,a=h?f.geometries.length:1,u=0;u<a;u++)if(p=h?f.geometries[u]:f,i=p.coordinates,d=!t||"Polygon"!==p.type&&"MultiPolygon"!==p.type?0:1,"Point"===p.type)o(i);else if("LineString"===p.type||"MultiPoint"===p.type)for(n=0;n<i.length;n++)o(i[n]);else if("Polygon"===p.type||"MultiLineString"===p.type)for(n=0;n<i.length;n++)for(c=0;c<i[n].length-d;c++)o(i[n][c]);else{if("MultiPolygon"!==p.type)throw new Error("Unknown Geometry Type");for(n=0;n<i.length;n++)for(c=0;c<i[n].length;c++)for(l=0;l<i[n][c].length-d;l++)o(i[n][c][l])}}function coordReduce(e,o,t,r){return coordEach(e,function(e){t=o(t,e)},r),t}function propEach(e,o){var t;switch(e.type){case"FeatureCollection":for(t=0;t<e.features.length;t++)o(e.features[t].properties);break;case"Feature":o(e.properties)}}function propReduce(e,o,t){return propEach(e,function(e){t=o(t,e)}),t}function featureEach(e,o){if("Feature"===e.type)return o(e);if("FeatureCollection"===e.type)for(var t=0;t<e.features.length;t++)o(e.features[t])}function coordAll(e){var o=[];return coordEach(e,function(e){o.push(e)}),o}module.exports.coordEach=coordEach,module.exports.coordReduce=coordReduce,module.exports.propEach=propEach,module.exports.propReduce=propReduce,module.exports.featureEach=featureEach,module.exports.coordAll=coordAll; },{}],3:[function(require,module,exports){ module.exports={bbox:require("turf-bbox")}; },{"turf-bbox":1}]},{},[3])(3) }); -
fxi revised this gist
Aug 30, 2016 . No changes.There are no files selected for viewing
-
fxi revised this gist
Aug 29, 2016 . 1 changed file with 41 additions and 13 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,22 +18,37 @@ <div id='map'></div> <script> /** * Generate a random string of the given length * @param {integer} n Number of character * @return {string} random string */ var randomString = function (n) { var result = ""; if( !n ) n=5; var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for( var i=0; i < n; i++ ) result += characters.charAt(Math.floor(Math.random() * characters.length)); return result; }; /** * Generate a random hsla color string, with fixed saturation and lightness * @param {number} opacity opacity from 0 to 1 * @param {number} random value from 0 to 1 * @param {number} saturation from 0 to 100 * @param {number} lightness from 0 to 100 */ var randomHsl = function (opacity, random, saturation, lightness) { if (!opacity) opacity = 1; if (!saturation) saturation = 100; if (!lightness) lightness = 50; if (!random) random = Math.random(); res = "hsla(" + (random * 360) + ", " + saturation + "% " + ", " + lightness + "% " + ", " + opacity + ")"; return res; }; // geojson type to mapbox gl type @@ -47,7 +62,7 @@ "GeometryCollection":"fill" }; // mapbox gl init mapboxgl.accessToken = 'pk.eyJ1IjoidW5lcGdyaWQiLCJhIjoiY2lzZnowenUwMDAzdjJubzZyZ3R1bjIzZyJ9.uyP-RWjY-94qCVajU0u8KA'; var map = new mapboxgl.Map({ container: 'map', @@ -56,6 +71,7 @@ zoom: 10 }); // test if file api is available if (window.File && window.FileReader && window.FileList && window.Blob) { function handleDropGeojson(evt) { evt.stopPropagation(); @@ -85,10 +101,13 @@ throw(x.message) } }) // get extent with geojsonExtent mapbox plugin var extent = geojsonExtent(gJson); // arra of types in data var geomTypes = [] ; // Get type for each feature gJson.features.forEach(function(x){ var g = x.geometry.type; @@ -102,34 +121,43 @@ throw(msg); } // Set random id for source and layer var id = "mgl_drop_" + geomTypes[0] + "_" + randomString(5); // Set random color var ran = Math.random(); var colA = randomHsl( 0.6, ran ); var colB = randomHsl( 0.8, ran ); // Set default type from geojson type var typ = typeSwitcher[geomTypes[0]]; // Set up default style var dummyStyle = { "circle": { "id" : id, "source":id, "type" : typ, "paint" : { "circle-color" : colA } }, "fill":{ "id":id, "source":id, "type":typ, "paint":{ "fill-color":colA, "fill-outline-color":colB } }, "line":{ "id":id, "source":id, "type":typ, "paint":{ "line-color":colA, "line-width":10 } } } -
fxi revised this gist
Aug 29, 2016 . 1 changed file with 12 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -24,12 +24,12 @@ }; var randomString = function(n){ var result = ""; if( !n ) n=5; var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for( var i=0; i < n; i++ ) result += characters.charAt(Math.floor(Math.random() * characters.length)); return result; }; var randomHsl = function (opacity) { if (!opacity) opacity = 1; @@ -82,7 +82,7 @@ console.log(x.message) }else{ alert(x.message) throw(x.message) } }) // get extent with geojsonExtent mapbox plugin @@ -96,11 +96,11 @@ geomTypes.push(g); }; }); if( geomTypes.length > 1){ var msg = "Multi geometry not yet implemented"; alert(msg); throw(msg); } var id = "mgl_drop_" + geomTypes[0] + "_" + randomString(5); var col = randomHsl(0.6); -
fxi created this gist
Aug 29, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,168 @@ <!DOCTYPE html> <html> <head> <meta charset='utf-8' /> <title></title> <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.23.0/mapbox-gl.js'></script> <script src='https://cdn.rawgit.com/mapbox/geojsonhint/master/geojsonhint.js'></script> <script src='https://cdn.rawgit.com/mapbox/geojson-extent/master/geojson-extent.js'></script> <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.23.0/mapbox-gl.css' rel='stylesheet' /> <style> body { margin:0; padding:0; } #map { position:absolute; top:0; bottom:0; width:100%; } </style> </head> <body> <div id='map'></div> <script> var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var randomString = function(n){ }; var randomString = function(n){ var result = ""; if( !n ) n=5; var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for( var i=0; i < n; i++ ) result += characters.charAt(Math.floor(Math.random() * characters.length)); return result; }; var randomHsl = function (opacity) { if (!opacity) opacity = 1; return "hsla(" + (Math.random() * 360) + ", 100%, 50%, " + opacity + ")"; }; // geojson type to mapbox gl type var typeSwitcher = { "Point":"circle", "MultiPoint":"line", "LineString":"line", "MultiLineString":"line", "Polygon":"fill", "MultiyPolygon":"fill", "GeometryCollection":"fill" }; mapboxgl.accessToken = 'pk.eyJ1IjoidW5lcGdyaWQiLCJhIjoiY2lzZnowenUwMDAzdjJubzZyZ3R1bjIzZyJ9.uyP-RWjY-94qCVajU0u8KA'; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v9', center: [15.6,-4.3], zoom: 10 }); if (window.File && window.FileReader && window.FileList && window.Blob) { function handleDropGeojson(evt) { evt.stopPropagation(); evt.preventDefault(); var files = evt.dataTransfer.files; // In case of multiple file, loop on them for (var i = 0, f; f = files[i]; i++) { // Only process geojson files. Validate later. if(f.name.indexOf(".geojson")==-1){ continue; } var reader = new FileReader(); reader.onload = (function(theFile) { return function(e) { gJson = JSON.parse(e.target.result); // handle simplified geojson validation var errors = geojsonhint.hint(gJson); errors.forEach(function(x){ if(x.level=="warn"){ console.log(x.message) }else{ alert(x.message) throw(x.message) } }) // get extent with geojsonExtent mapbox plugin var extent = geojsonExtent(gJson); // arra of types in data var geomTypes = [] ; // Get type for each feature gJson.features.forEach(function(x){ var g = x.geometry.type; if( geomTypes.length == 0 || geomTypes.indexOf(g) == -1 ){ geomTypes.push(g); }; }); if( geomTypes.length > 1){ var msg = "Multi geometry not yet implemented"; alert(msg); throw(msg); } var id = "mgl_drop_" + geomTypes[0] + "_" + randomString(5); var col = randomHsl(0.6); var typ = typeSwitcher[geomTypes[0]]; var dummyStyle = { "circle": { "id" : id, "source":id, "type" : typ, "paint" : { "circle-color":col } }, "fill":{ "id":id, "source":id, "type":typ, "paint":{ "fill-color":col } }, "line":{ "id":id, "source":id, "type":typ, "paint":{ "line-color":col, "line-width":5 } } } // Add source and layer; map.fitBounds(extent); map.addSource(id,{type:'geojson',data:gJson}); map.addLayer(dummyStyle[typ]); }; })(f); reader.readAsText(f); } } function handleDragOver(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. } // Set events mapEl = document.getElementById("map"); mapEl.addEventListener('dragover', handleDragOver, false); mapEl.addEventListener('drop', handleDropGeojson, false); } else { alert('The File APIs are not fully supported in this browser.'); } </script> </body> </html>