Commits (3)
...@@ -87,6 +87,8 @@ const regionChooser = (function(){ ...@@ -87,6 +87,8 @@ const regionChooser = (function(){
features_by_project = utils.groupBy(features, "project"); features_by_project = utils.groupBy(features, "project");
// Sort CityGMLs inside each project // Sort CityGMLs inside each project
Object.values(features_by_project).forEach(features => features.sort((a, b) => a.name.localeCompare(b.name))); Object.values(features_by_project).forEach(features => features.sort((a, b) => a.name.localeCompare(b.name)));
return features.length;
} }
// The features are not added to a regular vector layer/source, // The features are not added to a regular vector layer/source,
...@@ -292,10 +294,12 @@ const regionChooser = (function(){ ...@@ -292,10 +294,12 @@ const regionChooser = (function(){
function displayInfo() { function displayInfo() {
dataPanel.empty(); dataPanel.empty();
var geom = sketch.getGeometry().clone().transform(sourceProj, 'EPSG:4326'); var geom = sketch.getGeometry().clone().transform(sourceProj, 'EPSG:4326');
var coordinates = geom.getLinearRing(0).getCoordinates();
var area = Math.abs(wgs84Sphere.geodesicArea(coordinates)); if (utils.is_polygon(geom)){ // It could be a MultiPolygon, for example.
//NOTE: Could show m², ha or km² depending on magnitude var coordinates = geom.getLinearRing(0).getCoordinates();
dataPanel.append("<h3 class='clean'>Area : " + (area / 10000).toFixed(1) + " ha\n"); var area = Math.abs(wgs84Sphere.geodesicArea(coordinates));
dataPanel.append("<h3 class='clean'>Area : " + utils.human_readable_area(area) + "\n");
}
dataPanel.append('<div style="visibility:hidden" id="download_region">' + 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' + '<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(true);">(Select All)</a>\n' +
...@@ -379,7 +383,7 @@ const regionChooser = (function(){ ...@@ -379,7 +383,7 @@ const regionChooser = (function(){
//TODO: Show tooltip above. //TODO: Show tooltip above.
dataPanel.append("<form id='importWKT'>\n" + dataPanel.append("<form id='importWKT'>\n" +
"<input id='wktPolygon' type='text' placeholder='WKT Polygon' " + "<input id='wktPolygon' type='text' placeholder='WKT Polygon' " +
"required pattern=' *POLYGON *\\( *\\([\\-0-9\., \)\()]+\\) *\\) *' " + "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" + "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" + "<input type='submit' value='Import Polygon'/>\n" +
"</form>\n"); "</form>\n");
...@@ -404,18 +408,23 @@ const regionChooser = (function(){ ...@@ -404,18 +408,23 @@ const regionChooser = (function(){
featureProjection : ol.proj.get('EPSG:3857') featureProjection : ol.proj.get('EPSG:3857')
}); });
} catch (e){ } catch (e){
console.error("Couldn't import geometry!"); console.warn("Couldn't import geometry!");
dataPanel.prepend("<h2 class='error'>Couldn't import geometry!</h2><br/>\n"); dataPanel.prepend("<h2 class='error'>Couldn't import geometry!</h2><br/>\n");
return false; return false;
} }
// Assuming the linear ring is closed // Assuming the linear ring is closed
var coordinatesCount = feature.getGeometry().getLinearRing(0).getCoordinates().length - 1; var geom = feature.getGeometry();
if (coordinatesCount < 2){ if (utils.is_polygon(geom)){
console.error("Too few points!"); var coordinatesCount = geom.getLinearRing(0).getCoordinates().length - 1;
dataPanel.prepend("<h2 class='error'>There should be at least 2 points in WKT polygon</h2><br/>\n");
return false; 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;
}
} }
sketch = feature; sketch = feature;
...@@ -424,7 +433,7 @@ const regionChooser = (function(){ ...@@ -424,7 +433,7 @@ const regionChooser = (function(){
drawnLayer.getFeatures().clear(); drawnLayer.getFeatures().clear();
intersections.clear(); intersections.clear();
drawnLayer.addFeature(feature); drawnLayer.addFeature(feature);
map.getView().fitExtent(feature.getGeometry().getExtent(), map.getSize()); map.getView().fitExtent(geom.getExtent(), map.getSize());
displayInfo(); displayInfo();
draw.setActive(false); draw.setActive(false);
...@@ -437,8 +446,12 @@ const regionChooser = (function(){ ...@@ -437,8 +446,12 @@ const regionChooser = (function(){
// Executed by JavaFX when whole page is loaded. // Executed by JavaFX when whole page is loaded.
publicScope.ready = function() { publicScope.ready = function() {
updateGMLPolygons(); var n = updateGMLPolygons();
displayHelp(); displayHelp();
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");
}
document.documentElement.className = ''; // Stop waiting document.documentElement.className = ''; // Stop waiting
console.log("Ready!"); console.log("Ready!");
} }
...@@ -454,6 +467,10 @@ const regionChooser = (function(){ ...@@ -454,6 +467,10 @@ const regionChooser = (function(){
publicScope.copyCoordinatesToClipboard = function(){ publicScope.copyCoordinatesToClipboard = function(){
var geom = sketch.getGeometry().clone().transform(sourceProj, 'EPSG:4326'); var geom = sketch.getGeometry().clone().transform(sourceProj, 'EPSG:4326');
if (!utils.is_polygon(geom)){
console.warn("Sorry, can only export single polygons.");
return false;
}
var wgs84Coords = geom.getLinearRing(0).getCoordinates(); var wgs84Coords = geom.getLinearRing(0).getCoordinates();
var wktPolygon = "POLYGON(("; var wktPolygon = "POLYGON((";
var precision = 6; // ~ 10 cm precision var precision = 6; // ~ 10 cm precision
......
var utils = {}; var utils = {};
utils.groupBy = function(xs, key) { utils.groupBy = function (xs, key) {
return xs.reduce(function(rv, x) { return xs.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x); (rv[x[key]] = rv[x[key]] || []).push(x);
return rv; return rv;
}, {}); }, {});
} }
// Copies a string to the clipboard. Must be called from within an // Copies a string to the clipboard. Must be called from within an
// event handler such as click. May return false if it failed, but // event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+, // this is not always possible. Browser support for Chrome 43+,
...@@ -15,7 +15,7 @@ utils.groupBy = function(xs, key) { ...@@ -15,7 +15,7 @@ utils.groupBy = function(xs, key) {
// an administrator. By default a prompt is shown the first // an administrator. By default a prompt is shown the first
// time the clipboard is used (per session). // time the clipboard is used (per session).
// https://stackoverflow.com/a/33928558/6419007 // https://stackoverflow.com/a/33928558/6419007
utils.copyToClipboard = function(text, log) { utils.copyToClipboard = function (text, log) {
if (window.clipboardData && window.clipboardData.setData) { if (window.clipboardData && window.clipboardData.setData) {
// Internet Explorer-specific code path to prevent textarea being shown while dialog is visible. // Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
return window.clipboardData.setData("Text", text); return window.clipboardData.setData("Text", text);
...@@ -40,25 +40,39 @@ utils.copyToClipboard = function(text, log) { ...@@ -40,25 +40,39 @@ utils.copyToClipboard = function(text, log) {
} }
} }
} }
utils.read_kml = function(url){ utils.read_kml = function (url) {
return new ol.source.KML({ return new ol.source.KML({
projection : ol.proj.get('EPSG:3857'), projection: ol.proj.get('EPSG:3857'),
url : url, url: url,
extractAttributes : false, extractAttributes: false,
extractStyles : false extractStyles: false
}); });
} }
utils.polygon_style = function(color, alpha) { utils.is_polygon = function (geom) {
return ('getType' in geom) && (geom.getType() === 'Polygon');
}
utils.polygon_style = function (color, alpha) {
return new ol.style.Style({ return new ol.style.Style({
fill : new ol.style.Fill({ fill: new ol.style.Fill({
color : 'rgba(255, 255, 255,' + alpha + ')' color: 'rgba(255, 255, 255,' + alpha + ')'
}), }),
stroke : new ol.style.Stroke({ stroke: new ol.style.Stroke({
color : color, color: color,
width : 2, width: 2,
lineDash : [ 5, 10 ] lineDash: [5, 10]
}), }),
}); });
} }
utils.human_readable_area = function (area) {
if (area > 1_000_000) {
return (area / 1_000_000).toFixed(1) + " km²";
}
if (area > 10_000) {
return (area / 10_000).toFixed(1) + " ha";
}
return area.toFixed(1) + "";
}