Merge pull request #227 from nrenner/nogo-fixes
Nogo fixes for GeometryCollection geojson + minor UI
This commit is contained in:
commit
ce9e34283b
6 changed files with 140 additions and 112 deletions
|
|
@ -11,7 +11,7 @@
|
||||||
// TODO not included in permalink (better replace permalink with hash plugin)
|
// TODO not included in permalink (better replace permalink with hash plugin)
|
||||||
//BR.conf.transit = params.has('transit') && (params.get('transit') === 'true');
|
//BR.conf.transit = params.has('transit') && (params.get('transit') === 'true');
|
||||||
|
|
||||||
if (hostname === 'brouter.de' ) {
|
if (hostname === 'brouter.de') {
|
||||||
// online service (brouter.de) configuration
|
// online service (brouter.de) configuration
|
||||||
|
|
||||||
BR.conf.profiles = [
|
BR.conf.profiles = [
|
||||||
|
|
|
||||||
16
index.html
16
index.html
|
|
@ -457,7 +457,11 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p id="nogoError" style="display: none;"></p>
|
<p
|
||||||
|
id="nogoError"
|
||||||
|
class="invalid-feedback"
|
||||||
|
style="display: none;"
|
||||||
|
></p>
|
||||||
<form>
|
<form>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend data-i18n="loadNogos.source">
|
<legend data-i18n="loadNogos.source">
|
||||||
|
|
@ -478,10 +482,11 @@
|
||||||
<label
|
<label
|
||||||
for="nogoFile"
|
for="nogoFile"
|
||||||
data-i18n="loadNogos.file"
|
data-i18n="loadNogos.file"
|
||||||
>File:
|
>File (.geojson):
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
|
accept=".geojson"
|
||||||
name="nogoFile"
|
name="nogoFile"
|
||||||
id="nogoFile"
|
id="nogoFile"
|
||||||
/>
|
/>
|
||||||
|
|
@ -495,26 +500,28 @@
|
||||||
<label
|
<label
|
||||||
for="nogoWeight"
|
for="nogoWeight"
|
||||||
data-i18n="loadNogos.nogoWeight"
|
data-i18n="loadNogos.nogoWeight"
|
||||||
>No-go weight:
|
>No-go weight (-1 means impassable):
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
name="nogoWeight"
|
name="nogoWeight"
|
||||||
id="nogoWeight"
|
id="nogoWeight"
|
||||||
value="-1"
|
value="-1"
|
||||||
|
min="-1"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label
|
<label
|
||||||
for="nogoRadius"
|
for="nogoRadius"
|
||||||
data-i18n="loadNogos.nogoRadius"
|
data-i18n="loadNogos.nogoRadius"
|
||||||
>No-go radius (for points):
|
>No-go radius for points (in meters):
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
name="nogoRadius"
|
name="nogoRadius"
|
||||||
id="nogoRadius"
|
id="nogoRadius"
|
||||||
value="20"
|
value="20"
|
||||||
|
min="0"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -528,6 +535,7 @@
|
||||||
name="nogoBuffer"
|
name="nogoBuffer"
|
||||||
id="nogoBuffer"
|
id="nogoBuffer"
|
||||||
value="0"
|
value="0"
|
||||||
|
min="0"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
|
||||||
103
js/index.js
103
js/index.js
|
|
@ -409,109 +409,6 @@
|
||||||
$(this).collapse('show');
|
$(this).collapse('show');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#submitNogos').on('click', function() {
|
|
||||||
var geoJSONPromise;
|
|
||||||
var nogoURL = $('#nogoURL').val();
|
|
||||||
var nogoFile = $('#nogoFile')[0].files[0];
|
|
||||||
if (nogoURL) {
|
|
||||||
// TODO: Handle {{bbox}}
|
|
||||||
geoJSONPromise = fetch(nogoURL).then(function(response) {
|
|
||||||
response.json();
|
|
||||||
});
|
|
||||||
} else if (nogoFile) {
|
|
||||||
geoJSONPromise = new Promise(function(resolve, reject) {
|
|
||||||
var reader = new FileReader();
|
|
||||||
reader.onload = function() {
|
|
||||||
resolve(reader.result);
|
|
||||||
};
|
|
||||||
reader.readAsText(nogoFile);
|
|
||||||
}).then(function(response) {
|
|
||||||
return JSON.parse(response);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$('#nogoError').text('Error: Missing file or URL.');
|
|
||||||
$('#nogoError').css('display', 'block');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var nogoWeight = parseFloat($('#nogoWeight').val());
|
|
||||||
if (isNaN(nogoWeight)) {
|
|
||||||
$('#nogoError').text('Error: Missing default nogo weight.');
|
|
||||||
$('#nogoError').css('display', 'block');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var nogoRadius = parseFloat($('#nogoRadius').val());
|
|
||||||
if (isNaN(nogoRadius) || nogoRadius < 0) {
|
|
||||||
$('#nogoError').text('Error: Invalid default nogo radius.');
|
|
||||||
$('#nogoError').css('display', 'block');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var nogoBuffer = parseFloat($('#nogoBuffer').val());
|
|
||||||
if (isNaN(nogoBuffer)) {
|
|
||||||
$('#nogoError').text('Error: Invalid nogo buffering radius.');
|
|
||||||
$('#nogoError').css('display', 'block');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
geoJSONPromise.then(function(response) {
|
|
||||||
// Iterate on features in order to discard features without geometry
|
|
||||||
var cleanedGeoJSONFeatures = [];
|
|
||||||
turf.featureEach(response, function(feature) {
|
|
||||||
if (turf.getGeom(feature)) {
|
|
||||||
var maybeBufferedFeature = feature;
|
|
||||||
// Eventually buffer GeoJSON
|
|
||||||
if (nogoBuffer != 0) {
|
|
||||||
maybeBufferedFeature = turf.buffer(
|
|
||||||
maybeBufferedFeature,
|
|
||||||
nogoBuffer,
|
|
||||||
{ units: 'meters' }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
cleanedGeoJSONFeatures.push(maybeBufferedFeature);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var geoJSON = L.geoJson(
|
|
||||||
turf.featureCollection(cleanedGeoJSONFeatures),
|
|
||||||
{
|
|
||||||
onEachFeature: function(feature, layer) {
|
|
||||||
layer.options.nogoWeight =
|
|
||||||
feature.properties.nogoWeight || nogoWeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
var nogosPoints = geoJSON.getLayers().filter(function(e) {
|
|
||||||
return e.feature.geometry.type === 'Point';
|
|
||||||
});
|
|
||||||
nogosPoints = nogosPoints.map(function(item) {
|
|
||||||
var radius = item.feature.properties.radius || nogoRadius;
|
|
||||||
if (radius > 0) {
|
|
||||||
return L.circle(item.getLatLng(), { radius: radius });
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
nogosPoints = nogosPoints.filter(function(e) {
|
|
||||||
return e;
|
|
||||||
});
|
|
||||||
nogos.setOptions({
|
|
||||||
nogos: nogosPoints,
|
|
||||||
polygons: geoJSON.getLayers().filter(function(e) {
|
|
||||||
return e.feature.geometry.type === 'Polygon';
|
|
||||||
}),
|
|
||||||
polylines: geoJSON.getLayers().filter(function(e) {
|
|
||||||
return e.feature.geometry.type === 'LineString';
|
|
||||||
})
|
|
||||||
});
|
|
||||||
updateRoute({
|
|
||||||
options: nogos.getOptions()
|
|
||||||
});
|
|
||||||
urlHash.onMapMove();
|
|
||||||
$('#nogoError').text('');
|
|
||||||
$('#nogoError').css('display', 'none');
|
|
||||||
$('#loadNogos').modal('hide');
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i18next
|
i18next
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ BR.NogoAreas = L.Control.extend({
|
||||||
onAdd: function(map) {
|
onAdd: function(map) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
$('#submitNogos').on('click', L.bind(this.uploadNogos, this));
|
||||||
|
|
||||||
this.drawnItems = new L.FeatureGroup().addTo(map);
|
this.drawnItems = new L.FeatureGroup().addTo(map);
|
||||||
this.drawnItems.on('click', function(e) {
|
this.drawnItems.on('click', function(e) {
|
||||||
L.DomEvent.stop(e);
|
L.DomEvent.stop(e);
|
||||||
|
|
@ -118,6 +120,125 @@ BR.NogoAreas = L.Control.extend({
|
||||||
return L.DomUtil.create('div');
|
return L.DomUtil.create('div');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
displayUploadError: function(message) {
|
||||||
|
$('#nogoError').text(message ? message : '');
|
||||||
|
$('#nogoError').css('display', message ? 'block' : 'none');
|
||||||
|
},
|
||||||
|
|
||||||
|
uploadNogos: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var geoJSONPromise;
|
||||||
|
var nogoURL = $('#nogoURL').val();
|
||||||
|
var nogoFile = $('#nogoFile')[0].files[0];
|
||||||
|
if (nogoURL) {
|
||||||
|
// TODO: Handle {{bbox}}
|
||||||
|
geoJSONPromise = fetch(nogoURL).then(function(response) {
|
||||||
|
response.json();
|
||||||
|
});
|
||||||
|
} else if (nogoFile) {
|
||||||
|
geoJSONPromise = new Promise(function(resolve, reject) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function() {
|
||||||
|
resolve(reader.result);
|
||||||
|
};
|
||||||
|
reader.onerror = function() {
|
||||||
|
self.displayUploadError(
|
||||||
|
'Could not load file: ' + reader.error.message
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsText(nogoFile);
|
||||||
|
}).then(function(response) {
|
||||||
|
return JSON.parse(response);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// FIXME: use form validator instead
|
||||||
|
self.displayUploadError('Missing file or URL.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var nogoWeight = parseFloat($('#nogoWeight').val());
|
||||||
|
if (isNaN(nogoWeight)) {
|
||||||
|
// FIXME: use form validator instead
|
||||||
|
self.displayUploadError('Missing default nogo weight.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var nogoRadius = parseFloat($('#nogoRadius').val());
|
||||||
|
if (isNaN(nogoRadius) || nogoRadius < 0) {
|
||||||
|
// FIXME: use form validator instead
|
||||||
|
self.displayUploadError('Invalid default nogo radius.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var nogoBuffer = parseFloat($('#nogoBuffer').val());
|
||||||
|
if (isNaN(nogoBuffer)) {
|
||||||
|
// FIXME: use form validator instead
|
||||||
|
self.displayUploadError('Invalid nogo buffering radius.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
geoJSONPromise.then(function(response) {
|
||||||
|
// Iterate on features in order to discard features without geometry
|
||||||
|
var cleanedGeoJSONFeatures = [];
|
||||||
|
turf.flattenEach(response, function(feature) {
|
||||||
|
if (turf.getGeom(feature)) {
|
||||||
|
var maybeBufferedFeature = feature;
|
||||||
|
// Eventually buffer GeoJSON
|
||||||
|
if (nogoBuffer !== 0) {
|
||||||
|
maybeBufferedFeature = turf.buffer(
|
||||||
|
maybeBufferedFeature,
|
||||||
|
nogoBuffer,
|
||||||
|
{ units: 'meters' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
cleanedGeoJSONFeatures.push(maybeBufferedFeature);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cleanedGeoJSONFeatures.length === 0) {
|
||||||
|
self.displayUploadError(
|
||||||
|
'No valid area found in provided input.'
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var geoJSON = L.geoJson(
|
||||||
|
turf.featureCollection(cleanedGeoJSONFeatures),
|
||||||
|
{
|
||||||
|
onEachFeature: function(feature, layer) {
|
||||||
|
layer.options.nogoWeight =
|
||||||
|
feature.properties.nogoWeight || nogoWeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
var nogosPoints = geoJSON.getLayers().filter(function(e) {
|
||||||
|
return e.feature.geometry.type === 'Point';
|
||||||
|
});
|
||||||
|
nogosPoints = nogosPoints.map(function(item) {
|
||||||
|
var radius = item.feature.properties.radius || nogoRadius;
|
||||||
|
if (radius > 0) {
|
||||||
|
return L.circle(item.getLatLng(), { radius: radius });
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
nogosPoints = nogosPoints.filter(function(e) {
|
||||||
|
return e;
|
||||||
|
});
|
||||||
|
self.setOptions({
|
||||||
|
nogos: nogosPoints,
|
||||||
|
polygons: geoJSON.getLayers().filter(function(e) {
|
||||||
|
return e.feature.geometry.type === 'Polygon';
|
||||||
|
}),
|
||||||
|
polylines: geoJSON.getLayers().filter(function(e) {
|
||||||
|
return e.feature.geometry.type === 'LineString';
|
||||||
|
})
|
||||||
|
});
|
||||||
|
self._fireUpdate();
|
||||||
|
self.displayUploadError(undefined);
|
||||||
|
$('#loadNogos').modal('hide');
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
// prevent route waypoint added after circle create (map click after up)
|
// prevent route waypoint added after circle create (map click after up)
|
||||||
preventRoutePointOnCreate: function(routing) {
|
preventRoutePointOnCreate: function(routing) {
|
||||||
this.editTools.on(
|
this.editTools.on(
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
var brouterCgi = (function() {
|
var brouterCgi = (function() {
|
||||||
// http://brouter.de/cgi-bin/brouter.sh?coords=13.404681_52.520185_13.340278_52.512356_trekking_0
|
// http://brouter.de/cgi-bin/brouter.sh?coords=13.404681_52.520185_13.340278_52.512356_trekking_0
|
||||||
//var URL_TEMPLATE = '/cgi-bin/proxy.cgi?url=' + 'http://brouter.de/cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}';
|
//var URL_TEMPLATE = '/cgi-bin/proxy.cgi?url=' + 'http://brouter.de/cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}';
|
||||||
var URL_TEMPLATE = '/proxy.php?url=' + 'cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}';
|
var URL_TEMPLATE =
|
||||||
|
'/proxy.php?url=' +
|
||||||
|
'cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}';
|
||||||
var PRECISION = 6;
|
var PRECISION = 6;
|
||||||
|
|
||||||
function getUrl(polyline) {
|
function getUrl(polyline) {
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,11 @@
|
||||||
},
|
},
|
||||||
"loadNogos": {
|
"loadNogos": {
|
||||||
"defaultProperties": "Default properties",
|
"defaultProperties": "Default properties",
|
||||||
"file": "File: ",
|
"file": "File (.geojson): ",
|
||||||
"load": "Load",
|
"load": "Load",
|
||||||
"nogoBuffer": "Buffer no-go areas (in meters): ",
|
"nogoBuffer": "Buffer no-go areas (in meters): ",
|
||||||
"nogoRadius": "No-go radius (for points): ",
|
"nogoRadius": "No-go radius for points (in meters): ",
|
||||||
"nogoWeight": "No-go weight: ",
|
"nogoWeight": "No-go weight (-1 means impassable): ",
|
||||||
"source": "Source",
|
"source": "Source",
|
||||||
"title": "Load no-go areas",
|
"title": "Load no-go areas",
|
||||||
"url": "URL: "
|
"url": "URL: "
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue