Commit 03347ad7 authored by User expired's avatar User expired
Browse files

Implemented hierarchical isochrone analyses types

parent 92ab4d65
Upcoming version:
-----------------
- Implemented hierarchical isochrone analyses types (Nikolaus Krismer)
Version v0.9.0:
---------------
- Added some more information in isochrone analyses marker popups (Nikolaus Krismer)
......
......@@ -9,22 +9,23 @@
opacity: 0.5 !important;
}
/* Styles per type */
.analyse-school {
background-image: url('../images/analyse/school.png');
background-size: 100% 100%;
}
/* Inside styles per type */
/*
.analyse-inside-restaurant { }
*/
/* Outside styles per type */
/*
.analyse-outside-restaurant { }
.analyse-outside-school {
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-o-filter: grayscale(100%);
-ms-filter: grayscale(100%);
filter: grayscale(100%);
-webkit-filter: hue-rotate(280deg);
-moz-filter: hue-rotate(280deg);
-o-filter: hue-rotate(280deg);
-ms-filter: hue-rotate(280deg);
filter: hue-rotate(280deg);
}
*/
......@@ -3,11 +3,31 @@
*/
define(['jquery', 'leaflet', 'util/loggingUtils', '@turf/inside', 'spin.js', 'isochrone/configuration', 'util/geoUtils', 'util/languageUtils', '../../css/analyse.css'], function($, L, logger, tInside, Spinner, Configuration, GeoUtils, LanguageUtils) {
// Private static members
var FA_MAPPING = {
var CUSTOM_ICONS = [
'school'
],
FA_MAPPING = {
college: 'fa-graduation-cap',
kindergarten: 'fa-child',
restaurant: 'fa-cutlery',
school: 'fa-graduation-cap'
university: 'fa-university'
},
POPUP_MAPPING = {
POPUP_FN_DEFAULT = function(tags) {
var s = '';
if (!tags) {
return null;
}
if (tags.name) {
s += tags.name;
}
if (tags.website) {
s += '<br><br><a target="_blank" href="' + tags.website+ '">' + tags.website + '</a>';
}
return (s == '') ? null : s;
},
POPUP_FN_MAPPING = {
restaurant: function(tags) {
var s = '';
if (!tags) {
......@@ -27,29 +47,17 @@ define(['jquery', 'leaflet', 'util/loggingUtils', '@turf/inside', 'spin.js', 'is
s += '<br><a target="_blank" href="' + tags.website+ '">' + tags.website + '</a>';
}
return (s == '') ? null : s;
},
school: function(tags) {
var s = '';
if (!tags) {
return null;
}
if (tags.name) {
s += tags.name;
}
if (tags.website) {
s += '<br><br><a target="_blank" href="' + tags.website+ '">' + tags.website + '</a>';
}
return (s == '') ? null : s;
}
},
TYPE_HIERARCHIES = {
education: ['college', 'kindergarten', 'school', 'university']
};
function AnalyseHelper(iMap) {
var clusterMaxZoom = 14, // set to null to disable makerCluster
isoMap = null,
layerNames = null,
layerName = null,
osmUrl = window.location.protocol + '//overpass-api.de/api/interpreter?data=[out:json];'
+ '('
+ 'node[amenity=(AMENITY)](BBOX);'
......@@ -147,15 +155,12 @@ define(['jquery', 'leaflet', 'util/loggingUtils', '@turf/inside', 'spin.js', 'is
* @method AnalyseHelper#removeAllLayers
*/
function removeAllLayers() {
if (layerNames === null) {
if (layerName === null) {
return;
}
$.each(layerNames, function(name, value) {
isoMap.removeLayer(value);
});
layerNames = null;
isoMap.removeLayer(layerName);
layerName = null;
}
/**
......@@ -191,95 +196,141 @@ define(['jquery', 'leaflet', 'util/loggingUtils', '@turf/inside', 'spin.js', 'is
return null;
}
var analyseLayer = null,
var args = [],
arrDeferred = [],
allTypes = AnalyseHelper.getAvailableTypes(),
analyseLayer = null,
cntInside = null,
cntOutside = null,
cntTotal = null,
config = Configuration.getInstance(),
datasetConfigs = config.getDatasetConfigMap(),
ds = datasetConfigs[datasetName],
dsBBox = ds.bBoxLatLng,
dsBBoxMin = dsBBox._southWest,
dsBBoxMax = dsBBox._northEast,
fn = null,
i = 0,
inside = false,
isoLayers = [],
isoLayersGeoJSON = [],
layerName = LanguageUtils.get('analyse.type.' + type),
markers = [],
markersInLayer = 0,
osmBBox = [dsBBoxMin.lat, dsBBoxMin.lng, dsBBoxMax.lat, dsBBoxMax.lng],
strBBox = osmBBox.join(','),
types = AnalyseHelper.getAvailableTypes()[type],
useCoverageMask = config.useCoverageMask(),
url = osmUrl.replace(/(BBOX)/g, strBBox).replace(/(\(AMENITY\))/g, type);
url = null;
// prepare UI (remove old values...)
layerName = LanguageUtils.get('analyse.type.' + type);
if (TYPE_HIERARCHIES[type]) {
type = TYPE_HIERARCHIES[type];
} else {
type = [type];
}
logger.debug('Retrieving data from OSM:', url);
showLoadingSpinner();
updateFields({
inside: cntInside,
outside: cntOutside,
total: cntTotal
});
cntInside = cntOutside = cntTotal = 0;
for (i = 0; i < type.length; ++i) {
arrDeferred[i] = $.Deferred();
}
logger.debug(' - retrieving data for isochrone analyses:');
showLoadingSpinner();
isoLayers = getIsochroneLayers();
for (i = 0; i < isoLayers.length; ++i) {
isoLayersGeoJSON[i] = isoLayers[i].toGeoJSON();
}
$.getJSON(url, function(data) {
markers = [],
markersInLayer = 0;
$.each(data.elements, function(i, v) {
// if element is a way it does not contain lat/lon, but a center object containing lat/lon
var marker = null,
p = (v.center) ? v.center : v,
popupContent = null,
popupContentFn = POPUP_MAPPING[type];
inside = isPointInIsochrone(GeoUtils.toGeoJSONPoint([p.lon, p.lat]), isoLayersGeoJSON);
if (useCoverageMask) {
inside = !inside;
}
if (inside) {
++markersInLayer;
}
marker = L.marker(new L.latLng([p.lat, p.lon]), {
icon: types['icon' + ((inside) ? 'Inside' : 'Outside')]
// prepare and send ajax calls
for (i = 0; i < type.length; ++i) {
fn = function(callIndex, callObject, data) {
markers = [],
markersInLayer = 0;
$.each(data.elements, function(j, v) {
// if element is a way it does not contain lat/lon, but a center object containing lat/lon
var marker = null,
p = (v.center) ? v.center : v,
popupContent = null,
popupContentFn = POPUP_FN_MAPPING[t];
inside = isPointInIsochrone(GeoUtils.toGeoJSONPoint([p.lon, p.lat]), isoLayersGeoJSON);
if (useCoverageMask) {
inside = !inside;
}
if (inside) {
++markersInLayer;
}
marker = L.marker(new L.latLng([p.lat, p.lon]), {
icon: callObject['icon' + ((inside) ? 'Inside' : 'Outside')]
});
if (popupContentFn) {
popupContent = popupContentFn(v.tags);
} else {
popupContent = POPUP_FN_DEFAULT(v.tags);
}
if (popupContent != null) {
marker.bindPopup(popupContent);
}
markers[markers.length] = marker;
});
if (popupContentFn) {
popupContent = popupContentFn(v.tags);
}
if (popupContent == null && v.tags && v.tags.name) {
popupContent = v.tags.name;
}
if (popupContent != null) {
marker.bindPopup(popupContent);
cntInside += markersInLayer;
cntOutside += markers.length - markersInLayer;
cntTotal += markers.length;
if (clusterMaxZoom === null) {
analyseLayer = L.layerGroup(markers);
} else {
analyseLayer = L.markerClusterGroup({
animate: false,
disableClusteringAtZoom: clusterMaxZoom,
iconCreateFunction: function(cluster) {
var childCount = cluster.getChildCount();
return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster marker-cluster-analyse', iconSize: new L.Point(40, 40) });
},
spiderfyOnMaxZoom: false
});
analyseLayer.addLayers(markers);
}
markers[markers.length] = marker;
});
logger.debug(' - data from OSM receievd for call #' + (callIndex + 1));
arrDeferred[callIndex].resolve(analyseLayer);
};
t = type[i];
url = osmUrl.replace(/(BBOX)/g, strBBox).replace(/(\(AMENITY\))/g, t);
if (layerNames === null) {
layerNames = [];
}
layerNames[layerNames.length] = layerName;
logger.debug(' - from OSM (call #' + (i + 1) + '):', url);
$.getJSON(url, fn.bind(this, i, allTypes[t]));
}
if (clusterMaxZoom === null) {
analyseLayer = L.layerGroup(markers);
} else {
analyseLayer = L.markerClusterGroup({
animate: false,
disableClusteringAtZoom: clusterMaxZoom,
iconCreateFunction: function(cluster) {
var childCount = cluster.getChildCount();
return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster marker-cluster-analyse', iconSize: new L.Point(40, 40) });
},
spiderfyOnMaxZoom: false
// all ajax calls returned -> draw results
$.when.apply($, arrDeferred).then(function() {
args = Array.prototype.slice.call(arguments);
if (args.length > 1) {
analyseLayer = L.layerGroup();
$.each(args, function(layerIndex, layer) {
analyseLayer.addLayer(layer);
});
analyseLayer.addLayers(markers);
} else {
analyseLayer = args[0];
}
isoMap.addLayer(analyseLayer, layerName, true);
updateFields({
inside: markersInLayer,
outside: markers.length - markersInLayer,
total: markers.length
inside: cntInside,
outside: cntOutside,
total: cntTotal
});
});
}
......@@ -291,17 +342,25 @@ define(['jquery', 'leaflet', 'util/loggingUtils', '@turf/inside', 'spin.js', 'is
var i = 0,
name = null,
resultO = {},
types = ['school']; // custom types
types = CUSTOM_ICONS;
if (!types) {
types = [];
}
for (var faType in FA_MAPPING) {
types.push(faType);
}
for (var faType in TYPE_HIERARCHIES) {
types.push(faType);
}
types.sort();
for (i = 0; i < types.length; ++i) {
name = types[i];
resultO[name] = {
iconInside: createDefaultIcon(name, 'analyse-inside analyse-inside-' + name),
iconOutside: createDefaultIcon(name, 'analyse-outside analyse-outside-' + name)
iconInside: createDefaultIcon(name, 'analyse-' + name + ' analyse-inside analyse-inside-' + name),
iconOutside: createDefaultIcon(name, 'analyse-' + name + ' analyse-outside analyse-outside-' + name)
}
}
......@@ -327,8 +386,14 @@ define(['jquery', 'leaflet', 'util/loggingUtils', '@turf/inside', 'spin.js', 'is
iconAnchor: [6, 6]
};
if (CUSTOM_ICONS.indexOf(type) >= 0 && cssClassName) {
return L.divIcon($.extend({
className: cssClassName
}, iconSize));
}
if (!faClassName) {
faClassName = 'question';
faClassName = 'fa-question';
}
return L.divIcon($.extend({
......
......@@ -17,8 +17,12 @@
"outside": "Außerhalb des Isochrones",
"total": "Gesamtanzahl",
"type": {
"college": "Kolleg",
"education": "Bildung",
"kindergarten": "Kindergarten",
"restaurant": "Restaurants",
"school": "Schulen"
"school": "Schulen",
"university": "Universität"
}
},
"arrival": "Ankunft",
......
......@@ -15,8 +15,12 @@
"outside": "Outside of the isochrone",
"total": "Total",
"type": {
"college": "College",
"education": "Education",
"kindergarten": "Kindergarten",
"restaurant": "Restaurants",
"school": "Schools"
"school": "Schools",
"university": "University"
}
},
"arrival": "Arrival",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment