diff --git a/src/main/resources/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js b/src/main/resources/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js index 31689d30f786bb0b3a6338b0c6537eff9444f305..13b2da57da6769f12f64981e7f01e6d770915647 100644 --- a/src/main/resources/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js +++ b/src/main/resources/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js @@ -1,5 +1,5 @@ -const regionChooser = (function(){ +const regionChooser = (function () { //TODO: Somehow split in classes. This file is getting too big and mixed var publicScope = {}; const fromJavaFX = navigator.userAgent.indexOf('JavaFX') !== -1; @@ -13,13 +13,13 @@ const regionChooser = (function(){ styles.highlighted = utils.polygon_style("#ff44a2", 0.7); styles.selected = utils.polygon_style("#ffff00", 0.8); - publicScope.init = function(){ + publicScope.init = function () { //NOTE: Only called from JavaFX. At startup, or when Repo has been changed. kml_source.clear(); document.getElementById("select_repository").style.visibility = "visible"; } - if (fromJavaFX){ + if (fromJavaFX) { document.documentElement.className = 'wait'; } @@ -30,49 +30,49 @@ const regionChooser = (function(){ var kml_source = utils.read_kml(fromJavaFX ? undefined : 'data/citygml_hulls.kml'); var kml_layer = new ol.layer.Vector({ - source : kml_source, - style : styles.original + source: kml_source, + style: styles.original }); var intersections = new ol.source.Vector(); var intersections_layer = new ol.layer.Vector({ - source : intersections, - style : new ol.style.Style({ - fill : new ol.style.Fill({ - color : 'rgba(255, 155, 51, 0.2)' + source: intersections, + style: new ol.style.Style({ + fill: new ol.style.Fill({ + color: 'rgba(255, 155, 51, 0.2)' }) }) }); - publicScope.addCityGmlHull = function(kmlString) { - options = {featureProjection: ol.proj.get('EPSG:3857')}; + publicScope.addCityGmlHull = function (kmlString) { + options = { featureProjection: ol.proj.get('EPSG:3857') }; feature = kmlFormat.readFeature(kmlString, options); kml_source.addFeature(feature); dataPanel.append('.'); srsName = feature.get("srsName"); - if (proj4.defs(srsName) === undefined){ + if (proj4.defs(srsName) === undefined) { console.warn(srsName + " isn't defined by Proj4js!") } }; var map = new ol.Map({ - target : 'map', - layers : [ osm_layer, kml_layer, intersections_layer ], - interactions : ol.interaction.defaults({ - keyboard : true + target: 'map', + layers: [osm_layer, kml_layer, intersections_layer], + interactions: ol.interaction.defaults({ + keyboard: true }) }); const geoJsonFormat = new ol.format.GeoJSON(); - const kmlFormat = new ol.format.KML({extractStyles: false}); + const kmlFormat = new ol.format.KML({ extractStyles: false }); - kml_source.addEventListener("addfeature", function() { + kml_source.addEventListener("addfeature", function () { map.getView().fitExtent(kml_source.getExtent(), map.getSize()); }); function updateGMLPolygons() { - kml_source.forEachFeature(function(feature) { + kml_source.forEachFeature(function (feature) { feature["geoJSON"] = geoJsonFormat.writeFeatureObject(feature); feature["area"] = feature.getGeometry().getArea(); feature["project"] = feature.get("project"); @@ -96,57 +96,57 @@ const regionChooser = (function(){ // This collection is passed to the modify and also the draw // interaction, so that both can add or modify features. var drawnLayer = new ol.FeatureOverlay({ - style : new ol.style.Style({ - fill : new ol.style.Fill({ - color : 'rgba(255, 155, 51, 0.5)' + style: new ol.style.Style({ + fill: new ol.style.Fill({ + color: 'rgba(255, 155, 51, 0.5)' }), - stroke : new ol.style.Stroke({ - color : '#ffcc33', - width : 4 + stroke: new ol.style.Stroke({ + color: '#ffcc33', + width: 4 }), - image : new ol.style.Circle({ - radius : 5, - fill : new ol.style.Fill({ - color : '#ffcc33' + image: new ol.style.Circle({ + radius: 5, + fill: new ol.style.Fill({ + color: '#ffcc33' }) }) }) }); drawnLayer.setMap(map); - drawnLayer.getFeatures().on('add', function(event) { + drawnLayer.getFeatures().on('add', function (event) { var feature = event.element; - feature.on("change", function() { + feature.on("change", function () { displayInfo(); }); }); var modify = new ol.interaction.Modify({ - features : drawnLayer.getFeatures(), + features: drawnLayer.getFeatures(), // the SHIFT key must be pressed to delete vertices, so // that new vertices can be drawn at the same position // of existing vertices - deleteCondition : function(event) { + deleteCondition: function (event) { return ol.events.condition.shiftKeyOnly(event) && ol.events.condition.singleClick(event); } }); map.addInteraction(modify); var draw = new ol.interaction.Draw({ - features : drawnLayer.getFeatures(), - type : 'Polygon' + features: drawnLayer.getFeatures(), + type: 'Polygon' }); map.addInteraction(draw); var sketch; - draw.on('drawstart', function(evt) { + draw.on('drawstart', function (evt) { sketch = evt.feature; updateGMLPolygons(); }); var sourceProj = map.getView().getProjection(); - function showLinkToDownload(feature, jsonIntersection, polygonArea){ + function showLinkToDownload(feature, jsonIntersection, polygonArea) { var intersection = geoJsonFormat.readFeature(jsonIntersection); var intersectionArea = intersection.getGeometry().getArea(); var citygml_percentage = Math.round(intersectionArea / feature["area"] * 100); @@ -156,8 +156,8 @@ const regionChooser = (function(){ li = document.createElement('li'); li.feature = feature; - li.onmouseover = function(){ regionChooser.highlightPolygon(this.feature) }; - li.onmouseout = function(){ regionChooser.resetHighlight(this.feature) }; + li.onmouseover = function () { regionChooser.highlightPolygon(this.feature) }; + li.onmouseout = function () { regionChooser.resetHighlight(this.feature) }; let label = li.appendChild(document.createElement('label')); var text = feature.name; @@ -180,22 +180,22 @@ const regionChooser = (function(){ dataPanel[0].appendChild(li); } - publicScope.highlightPolygon = function(feature) { + publicScope.highlightPolygon = function (feature) { feature.setStyle(styles.highlighted); } - publicScope.resetHighlight = function(feature) { + publicScope.resetHighlight = function (feature) { refreshStyle(feature); } - refreshStyle = function(feature, status){ - if (status){ + refreshStyle = function (feature, status) { + if (status) { feature.status = status; } feature.setStyle(styles[feature.status]); } - publicScope.isDownloadPossible = function(){ + publicScope.isDownloadPossible = function () { kml_source.getFeatures().forEach(f => refreshStyle(f, "original")); selectedFeatures = getSelectedGMLs(); @@ -205,7 +205,7 @@ const regionChooser = (function(){ document.getElementById("download_region_button").disabled = (selectedFeatures.length == 0); } - function getSelectedGMLs(){ + function getSelectedGMLs() { return Array.from(document.querySelectorAll("input.select_citygml")).filter(c => c.checked).map(c => c.feature); } @@ -223,10 +223,10 @@ const regionChooser = (function(){ var intersection_found = false; intersections.clear(); - Object.keys(features_by_project).forEach(function(project) { + Object.keys(features_by_project).forEach(function (project) { features = features_by_project[project]; - features_and_intersections = features.map(f=> [f, findIntersection(f,polygon)]).filter(l => l[1] !== undefined); - if (features_and_intersections.length > 0){ + features_and_intersections = features.map(f => [f, findIntersection(f, polygon)]).filter(l => l[1] !== undefined); + if (features_and_intersections.length > 0) { intersection_found = true; dataPanel.append("<h2 class='info'>" + project); features_and_intersections.forEach(l => showLinkToDownload(l[0], l[1], polygonArea)); @@ -242,46 +242,46 @@ const regionChooser = (function(){ } } - publicScope.display = function(text){ + publicScope.display = function (text) { dataPanel.append(text + "<br/>\n"); } - publicScope.downloadStart = function(){ + publicScope.downloadStart = function () { document.getElementById("download_region_button").disabled = true; document.documentElement.className = 'wait'; dataPanel.prepend("<h2 id='download_start' class='ok'>Extracting region...</h2><br/>\n"); } - publicScope.downloadFinished = function(count){ + publicScope.downloadFinished = function (count) { document.documentElement.className = ''; // Stop waiting document.getElementById("download_start").remove(); - if (count > 0){ + if (count > 0) { dataPanel.prepend("<h2 class='ok'>Done! (" + count + " buildings found) </h2><br/>\n"); } else { dataPanel.prepend("<h2 class='error'>No building has been found in this region</h2><br/>\n"); } var button = document.getElementById("download_region_button"); - if (button){ // Region might have been modified since download start + if (button) { // Region might have been modified since download start button.disabled = false; } } - publicScope.downloadFromSelectedCityGMLs = function() { + publicScope.downloadFromSelectedCityGMLs = function () { var features = getSelectedGMLs(); var project = features[0].get("project"); var srsName = features[0].get("srsName"); - if (!features.every( f => f.get("project") === project)){ + if (!features.every(f => f.get("project") === project)) { dataPanel.prepend("<h2 class='error'>Sorry, the CityGML files should all belong to the same project.</h2><br/>\n"); return; } - if (!features.every( f => f.get("srsName") === srsName)){ + if (!features.every(f => f.get("srsName") === srsName)) { dataPanel.prepend("<h2 class='error'>Sorry, the CityGML files should all be written with the same coordinate system.</h2><br/>\n"); } var citygmlNames = features.map(f => f.get("name")); - if (proj4.defs(srsName)){ + if (proj4.defs(srsName)) { console.log("Selected region is written in " + srsName + " coordinate system."); fxapp.downloadRegionFromCityGMLs(sketchAsWKT(srsName), project, citygmlNames.join(";"), srsName); } else { @@ -295,7 +295,7 @@ const regionChooser = (function(){ dataPanel.empty(); var geom = sketch.getGeometry().clone().transform(sourceProj, 'EPSG:4326'); - if (utils.is_polygon(geom)){ // It could be a MultiPolygon, for example. + if (utils.is_polygon(geom)) { // It could be a MultiPolygon, for example. var coordinates = geom.getLinearRing(0).getCoordinates(); var area = Math.abs(wgs84Sphere.geodesicArea(coordinates)); dataPanel.append("<h3 class='clean'>Area : " + utils.human_readable_area(area) + "\n"); @@ -303,31 +303,31 @@ const regionChooser = (function(){ dataPanel.append('<div style="visibility:hidden" id="download_region">' + '<button type="button" onclick="regionChooser.downloadFromSelectedCityGMLs()" id="download_region_button" disabled>Download Region</button><br/>\n' + '<a href="#" onclick="regionChooser.selectAllOrNone(true);">(Select All)</a>\n' + - '<a href="#" onclick="regionChooser.selectAllOrNone(false);">(Select None)</a>\n'+ + '<a href="#" onclick="regionChooser.selectAllOrNone(false);">(Select None)</a>\n' + '</div>\n'); findIntersections(); dataPanel.append('<button type="button" onclick="regionChooser.copyCoordinatesToClipboard()" id="get_wgs84" style="position:fixed; bottom:0;">Copy coordinates</button><br/>\n') } - draw.on('drawend', function() { + draw.on('drawend', function () { displayInfo(); draw.setActive(false); }); // With OpenLayers 3.9, draw_interaction.removeLastPoint(); might be better. - document.addEventListener('keydown', function(e) { + document.addEventListener('keydown', function (e) { //NOTE: e.key isn't defined in JavaFX Browser - if (e.which == 27 || e.which == 46){ // ESCAPE or DELETE. + if (e.which == 27 || e.which == 46) { // ESCAPE or DELETE. resetDrawing(); } - if (e.which == 116 && fromJavaFX){ // F5 for refresh + if (e.which == 116 && fromJavaFX) { // F5 for refresh dataPanel.prepend("<h2 class='ok'>Refreshing repository...</h2><br/>\n"); document.documentElement.className = 'wait'; fxapp.refreshHulls(); } }); - function resetDrawing(){ + function resetDrawing() { console.log("Reset drawing"); try { draw.finishDrawing(); @@ -345,8 +345,8 @@ const regionChooser = (function(){ function sketchAsWKT(srsName) { var wktFormat = new ol.format.WKT(); return wktFormat.writeFeature(sketch, { - dataProjection : ol.proj.get(srsName), - featureProjection : ol.proj.get('EPSG:3857') + dataProjection: ol.proj.get(srsName), + featureProjection: ol.proj.get('EPSG:3857') }); } @@ -356,18 +356,18 @@ const regionChooser = (function(){ var fxapp = undefined; - publicScope.setFxApp = function(app){ + publicScope.setFxApp = function (app) { fxapp = app; - console.log = function(message){ + console.log = function (message) { fxapp.log(message); } - console.warn = function(message){ + console.warn = function (message) { fxapp.warning(message); } } - function displayHelp(){ + function displayHelp() { dataPanel.empty(); dataPanel.append("<h2 class='info'>Welcome to Region Chooser!<br><br>\n"); dataPanel.append("You can draw a polygon on the map by clicking.<br>\n"); @@ -382,15 +382,15 @@ const regionChooser = (function(){ dataPanel.append("<a href='http://simstadt.hft-stuttgart.de/related-softwares/region-chooser/'>SimStadt documentation</a><br>\n"); //TODO: Show tooltip above. dataPanel.append("<form id='importWKT'>\n" + - "<input id='wktPolygon' type='text' placeholder='WKT Polygon' " + - "required pattern=' *(MULTI)?POLYGON *\\( *\\([\\-0-9\., \)\()]+\\) *\\) *' " + - "title='Please input a valid WKT Polygon. Example : POLYGON((9.961675 49.807053, 9.951375 49.798521, 9.969486 49.797746, 9.961675 49.807053)) '/>\n" + - "<input type='submit' value='Import Polygon'/>\n" + - "</form>\n"); + "<input id='wktPolygon' type='text' placeholder='WKT Polygon' " + + "required pattern=' *(MULTI)?POLYGON *\\( *\\([\\-0-9\., \)\()]+\\) *\\) *' " + + "title='Please input a valid WKT Polygon. Example : POLYGON((9.961675 49.807053, 9.951375 49.798521, 9.969486 49.797746, 9.961675 49.807053)) '/>\n" + + "<input type='submit' value='Import Polygon'/>\n" + + "</form>\n"); document.getElementById('importWKT').addEventListener('submit', importWKT); } - importWKT = function(e){ + importWKT = function (e) { e.preventDefault(); // to avoid refresh @@ -402,12 +402,12 @@ const regionChooser = (function(){ var wktFormat = new ol.format.WKT(); - try{ + try { var feature = wktFormat.readFeature(wktPolygon, { - dataProjection : ol.proj.get('EPSG:4326'), - featureProjection : ol.proj.get('EPSG:3857') + dataProjection: ol.proj.get('EPSG:4326'), + featureProjection: ol.proj.get('EPSG:3857') }); - } catch (e){ + } catch (e) { console.warn("Couldn't import geometry!"); dataPanel.prepend("<h2 class='error'>Couldn't import geometry!</h2><br/>\n"); return false; @@ -417,10 +417,10 @@ const regionChooser = (function(){ // Assuming the linear ring is closed var geom = feature.getGeometry(); - if (utils.is_polygon(geom)){ + if (utils.is_polygon(geom)) { var coordinatesCount = geom.getLinearRing(0).getCoordinates().length - 1; - if (coordinatesCount < 2){ + if (coordinatesCount < 2) { console.warn("Too few points!"); dataPanel.prepend("<h2 class='error'>There should be at least 2 points in WKT polygon</h2><br/>\n"); return false; @@ -445,10 +445,10 @@ const regionChooser = (function(){ } // Executed by JavaFX when whole page is loaded. - publicScope.ready = function() { + publicScope.ready = function () { var n = updateGMLPolygons(); displayHelp(); - if (n == 0){ + if (n == 0) { console.warn("No CityGML found!"); dataPanel.prepend("<h2 class='error'>No CityGML has been found!<br/>repository/name.proj/file.gml</h2><br/>\n"); } @@ -456,18 +456,18 @@ const regionChooser = (function(){ console.log("Ready!"); } - publicScope.selectAllOrNone = function(allOrNone) { + publicScope.selectAllOrNone = function (allOrNone) { document.querySelectorAll("input.select_citygml").forEach(c => c.checked = allOrNone); publicScope.isDownloadPossible(); } - publicScope.selectRepository = function() { + publicScope.selectRepository = function () { fxapp.selectRepository(); } - publicScope.copyCoordinatesToClipboard = function(){ + publicScope.copyCoordinatesToClipboard = function () { var geom = sketch.getGeometry().clone().transform(sourceProj, 'EPSG:4326'); - if (!utils.is_polygon(geom)){ + if (!utils.is_polygon(geom)) { console.warn("Sorry, can only export single polygons."); return false; } @@ -478,7 +478,7 @@ const regionChooser = (function(){ utils.copyToClipboard(wktPolygon + "))", dataPanel); } - publicScope.showRepositoryName = function(path) { + publicScope.showRepositoryName = function (path) { document.getElementById("repo_path").textContent = path; }