Remove JS

This commit is contained in:
Pieter Vander Vennet 2020-07-20 20:15:21 +02:00
parent 2f510e9143
commit 14a5c7406a
18 changed files with 2 additions and 2152 deletions

View file

@ -1,70 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Basemap = void 0;
var leaflet_1 = require("leaflet");
var UIEventSource_1 = require("../UI/UIEventSource");
// Contains all setup and baselayers for Leaflet stuff
var Basemap = /** @class */ (function () {
function Basemap(leafletElementId, location, extraAttribution) {
this.LastClickLocation = new UIEventSource_1.UIEventSource(undefined);
this.aivLucht2013Layer = leaflet_1.default.tileLayer.wms('https://geoservices.informatievlaanderen.be/raadpleegdiensten/OGW/wms?s', {
layers: "OGWRGB13_15VL",
attribution: "Luchtfoto's van © AIV Vlaanderen (2013-2015) | "
});
this.aivLuchtLatestLayer = leaflet_1.default.tileLayer("https://tile.informatievlaanderen.be/ws/raadpleegdiensten/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&" +
"LAYER=omwrgbmrvl&STYLE=&FORMAT=image/png&tileMatrixSet=GoogleMapsVL&tileMatrix={z}&tileRow={y}&tileCol={x}", {
// omwrgbmrvl
attribution: 'Luchtfoto\'s van © AIV Vlaanderen (Laatste) © AGIV',
maxZoom: 20,
minZoom: 1,
wmts: true
});
this.osmLayer = leaflet_1.default.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: '',
maxZoom: 19,
minZoom: 1
});
this.osmBeLayer = leaflet_1.default.tileLayer("https://tile.osm.be/osmbe/{z}/{x}/{y}.png", {
attribution: '<a href="https://geo6.be/">Tile hosting courtesy of Geo6</a>',
maxZoom: 18,
minZoom: 1
});
this.grbLayer = leaflet_1.default.tileLayer("https://tile.informatievlaanderen.be/ws/raadpleegdiensten/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=grb_bsk&STYLE=&FORMAT=image/png&tileMatrixSet=GoogleMapsVL&tileMatrix={z}&tileCol={x}&tileRow={y}", {
attribution: 'Achtergrond <i>Grootschalig ReferentieBestand</i>(GRB) © AGIV',
maxZoom: 20,
minZoom: 1,
wmts: true
});
this.baseLayers = {
"Luchtfoto Vlaanderen (recentste door AIV)": this.aivLuchtLatestLayer,
"Luchtfoto Vlaanderen (2013-2015, door AIV)": this.aivLucht2013Layer,
"Kaart van OpenStreetMap": this.osmLayer,
"Kaart Grootschalig ReferentieBestand Vlaanderen (GRB) door AIV": this.grbLayer
};
this.map = leaflet_1.default.map(leafletElementId, {
center: [location.data.lat, location.data.lon],
zoom: location.data.zoom,
layers: [this.osmLayer],
});
this.map.attributionControl.setPrefix(extraAttribution.Render() + " | <a href='https://osm.org'>OpenStreetMap</a>");
this.Location = location;
var layerControl = leaflet_1.default.control.layers(this.baseLayers, null, {
position: 'bottomright',
hideSingleBase: true
});
layerControl.addTo(this.map);
this.map.zoomControl.setPosition("bottomright");
var self = this;
this.map.on("moveend", function () {
location.data.zoom = self.map.getZoom();
location.data.lat = self.map.getCenter().lat;
location.data.lon = self.map.getCenter().lng;
location.ping();
});
this.map.on("click", function (e) {
self.LastClickLocation.setData({ lat: e.latlng.lat, lon: e.latlng.lng });
});
}
return Basemap;
}());
exports.Basemap = Basemap;

View file

@ -1,222 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Changes = void 0;
var OsmObject_1 = require("./OsmObject");
var UIEventSource_1 = require("../UI/UIEventSource");
var TagsFilter_1 = require("./TagsFilter");
var Changes = /** @class */ (function () {
function Changes(changesetComment, login, allElements) {
this._pendingChanges = []; // Gets reset on uploadAll
this.newElements = []; // Gets reset on uploadAll
this.pendingChangesES = new UIEventSource_1.UIEventSource(this._pendingChanges.length);
this.isSaving = new UIEventSource_1.UIEventSource(false);
this._changesetComment = changesetComment;
this.login = login;
this._allElements = allElements;
}
Changes.prototype.addTag = function (elementId, tagsFilter) {
if (tagsFilter instanceof TagsFilter_1.Tag) {
var tag = tagsFilter;
this.addChange(elementId, tag.key, tag.value);
return;
}
if (tagsFilter instanceof TagsFilter_1.And) {
var and = tagsFilter;
for (var _i = 0, _a = and.and; _i < _a.length; _i++) {
var tag = _a[_i];
this.addTag(elementId, tag);
}
return;
}
console.log("Unsupported tagsfilter element to addTag", tagsFilter);
throw "Unsupported tagsFilter element";
};
/**
* Adds a change to the pending changes
* @param elementId
* @param key
* @param value
*/
Changes.prototype.addChange = function (elementId, key, value) {
console.log("Received change", key, value);
if (key === undefined || key === null) {
console.log("Invalid key");
return;
}
if (value === undefined || value === null) {
console.log("Invalid value for ", key);
return;
}
var eventSource = this._allElements.getElement(elementId);
eventSource.data[key] = value;
eventSource.ping();
// We get the id from the event source, as that ID might be rewritten
this._pendingChanges.push({ elementId: eventSource.data.id, key: key, value: value });
this.pendingChangesES.setData(this._pendingChanges.length);
};
/**
* Create a new node element at the given lat/long.
* An internal OsmObject is created to upload later on, a geojson represention is returned.
* Note that the geojson version shares the tags (properties) by pointer, but has _no_ id in properties
*/
Changes.prototype.createElement = function (basicTags, lat, lon) {
var osmNode = new OsmObject_1.OsmNode(Changes._nextId);
this.newElements.push(osmNode);
Changes._nextId--;
var id = "node/" + osmNode.id;
osmNode.lat = lat;
osmNode.lon = lon;
var properties = { id: id };
var geojson = {
"type": "Feature",
"properties": properties,
"id": id,
"geometry": {
"type": "Point",
"coordinates": [
lon,
lat
]
}
};
this._allElements.addOrGetElement(geojson);
// The basictags are COPIED, the id is included in the properties
// The tags are not yet written into the OsmObject, but this is applied onto a
for (var _i = 0, basicTags_1 = basicTags; _i < basicTags_1.length; _i++) {
var kv = basicTags_1[_i];
this.addChange(id, kv.key, kv.value); // We use the call, to trigger all the other machinery (including updating the geojson itsel
properties[kv.key] = kv.value;
}
return geojson;
};
Changes.prototype.uploadAll = function (optionalContinuation) {
if (optionalContinuation === void 0) { optionalContinuation = undefined; }
var self = this;
this.isSaving.setData(true);
var optionalContinuationWrapped = function () {
self.isSaving.setData(false);
if (optionalContinuation) {
optionalContinuation();
}
};
var pending = this._pendingChanges;
this._pendingChanges = [];
this.pendingChangesES.setData(this._pendingChanges.length);
var newElements = this.newElements;
this.newElements = [];
var knownElements = {}; // maps string --> OsmObject
function DownloadAndContinue(neededIds, continuation) {
// local function which downloads all the objects one by one
// this is one big loop, running one download, then rerunning the entire function
if (neededIds.length == 0) {
continuation();
return;
}
var neededId = neededIds.pop();
if (neededId in knownElements) {
DownloadAndContinue(neededIds, continuation);
return;
}
console.log("Downloading ", neededId);
OsmObject_1.OsmObject.DownloadObject(neededId, function (element) {
knownElements[neededId] = element; // assign the element for later, continue downloading the next element
DownloadAndContinue(neededIds, continuation);
});
}
var neededIds = [];
for (var _i = 0, pending_1 = pending; _i < pending_1.length; _i++) {
var change = pending_1[_i];
var id = change.elementId;
if (parseFloat(id.split("/")[1]) < 0) {
console.log("Detected a new element! Exciting!");
}
else {
neededIds.push(id);
}
}
DownloadAndContinue(neededIds, function () {
// Here, inside the continuation, we know that all 'neededIds' are loaded in 'knownElements'
// We apply the changes on them
for (var _i = 0, pending_2 = pending; _i < pending_2.length; _i++) {
var change = pending_2[_i];
if (parseInt(change.elementId.split("/")[1]) < 0) {
// This is a new element - we should apply this on one of the new elements
for (var _a = 0, newElements_1 = newElements; _a < newElements_1.length; _a++) {
var newElement = newElements_1[_a];
if (newElement.type + "/" + newElement.id === change.elementId) {
newElement.addTag(change.key, change.value);
}
}
}
else {
console.log(knownElements, change.elementId);
knownElements[change.elementId].addTag(change.key, change.value);
// note: addTag will flag changes with 'element.changed' internally
}
}
// Small sanity check for duplicate information
var changedElements = [];
for (var elementId in knownElements) {
var element = knownElements[elementId];
if (element.changed) {
changedElements.push(element);
}
}
if (changedElements.length == 0 && newElements.length == 0) {
console.log("No changes in any object");
return;
}
var handleMapping = function (idMapping) {
for (var oldId in idMapping) {
var newId = idMapping[oldId];
var element = self._allElements.getElement(oldId);
element.data.id = newId;
self._allElements.addElementById(newId, element);
element.ping();
}
};
console.log("Beginning upload...");
// At last, we build the changeset and upload
self.login.UploadChangeset(self._changesetComment, function (csId) {
var modifications = "";
for (var _i = 0, changedElements_1 = changedElements; _i < changedElements_1.length; _i++) {
var element = changedElements_1[_i];
if (!element.changed) {
continue;
}
modifications += element.ChangesetXML(csId) + "\n";
}
var creations = "";
for (var _a = 0, newElements_2 = newElements; _a < newElements_2.length; _a++) {
var newElement = newElements_2[_a];
creations += newElement.ChangesetXML(csId);
}
var changes = "<osmChange version='0.6' generator='Mapcomplete 0.0.1'>";
if (creations.length > 0) {
changes +=
"<create>" +
creations +
"</create>";
}
if (modifications.length > 0) {
changes +=
"<modify>" +
modifications +
"</modify>";
}
changes += "</osmChange>";
return changes;
}, handleMapping, optionalContinuationWrapped);
});
};
Changes.prototype.asQuestions = function (qs) {
var ls = [];
for (var i in qs) {
ls.push(new Question(this, qs[i]));
}
return ls;
};
Changes._nextId = -1; // New assined ID's are negative
return Changes;
}());
exports.Changes = Changes;

View file

@ -1,51 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ElementStorage = void 0;
/**
* Keeps track of a dictionary 'elementID' -> element
*/
var UIEventSource_1 = require("../UI/UIEventSource");
var ElementStorage = /** @class */ (function () {
function ElementStorage() {
this._elements = [];
}
ElementStorage.prototype.addElementById = function (id, eventSource) {
this._elements[id] = eventSource;
};
ElementStorage.prototype.addElement = function (element) {
var eventSource = new UIEventSource_1.UIEventSource(element.properties);
this._elements[element.properties.id] = eventSource;
return eventSource;
};
ElementStorage.prototype.addOrGetElement = function (element) {
var elementId = element.properties.id;
if (elementId in this._elements) {
var es = this._elements[elementId];
var keptKeys = es.data;
// The element already exists
// We add all the new keys to the old keys
for (var k in element.properties) {
var v = element.properties[k];
if (keptKeys[k] !== v) {
keptKeys[k] = v;
es.ping();
}
}
return es;
}
else {
return this.addElement(element);
}
};
ElementStorage.prototype.getElement = function (elementId) {
if (elementId in this._elements) {
return this._elements[elementId];
}
console.log("Can not find eventsource with id ", elementId);
};
ElementStorage.prototype.removeId = function (oldId) {
delete this._elements[oldId];
};
return ElementStorage;
}());
exports.ElementStorage = ElementStorage;

View file

@ -1,173 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FilteredLayer = void 0;
var TagsFilter_1 = require("./TagsFilter");
var UIEventSource_1 = require("../UI/UIEventSource");
var leaflet_1 = require("leaflet");
var GeoOperations_1 = require("./GeoOperations");
/***
* A filtered layer is a layer which offers a 'set-data' function
* It is initialized with a tagfilter.
*
* When geojson-data is given to 'setData', all the geojson matching the filter, is rendered on this layer.
* If it is not rendered, it is returned in a 'leftOver'-geojson; which can be consumed by the next layer.
*
* This also makes sure that no objects are rendered twice if they are applicable on two layers
*/
var FilteredLayer = /** @class */ (function () {
function FilteredLayer(name, map, storage, changes, filters, maxAllowedOverlap, style, selectedElement, showOnPopup) {
this.isDisplayed = new UIEventSource_1.UIEventSource(true);
/** List of new elements, geojson features
*/
this._newElements = [];
this._selectedElement = selectedElement;
this._showOnPopup = showOnPopup;
if (style === undefined) {
style = function () {
return {};
};
}
this.name = name;
this._map = map;
this.filters = filters;
this._style = style;
this._storage = storage;
this._maxAllowedOverlap = maxAllowedOverlap;
var self = this;
this.isDisplayed.addCallback(function (isDisplayed) {
if (self._geolayer !== undefined && self._geolayer !== null) {
if (isDisplayed) {
self._geolayer.addTo(self._map.map);
}
else {
self._map.map.removeLayer(self._geolayer);
}
}
});
}
/**
* The main function to load data into this layer.
* The data that is NOT used by this layer, is returned as a geojson object; the other data is rendered
*/
FilteredLayer.prototype.SetApplicableData = function (geojson) {
var leftoverFeatures = [];
var selfFeatures = [];
for (var _i = 0, _a = geojson.features; _i < _a.length; _i++) {
var feature = _a[_i];
// feature.properties contains all the properties
var tags = TagsFilter_1.TagUtils.proprtiesToKV(feature.properties);
if (this.filters.matches(tags)) {
selfFeatures.push(feature);
}
else {
leftoverFeatures.push(feature);
}
}
this.RenderLayer({
type: "FeatureCollection",
features: selfFeatures
});
var notShadowed = [];
for (var _b = 0, leftoverFeatures_1 = leftoverFeatures; _b < leftoverFeatures_1.length; _b++) {
var feature = leftoverFeatures_1[_b];
if (this._maxAllowedOverlap !== undefined && this._maxAllowedOverlap > 0) {
if (GeoOperations_1.GeoOperations.featureIsContainedInAny(feature, selfFeatures, this._maxAllowedOverlap)) {
// This feature is filtered away
continue;
}
}
notShadowed.push(feature);
}
return {
type: "FeatureCollection",
features: notShadowed
};
};
FilteredLayer.prototype.AddNewElement = function (element) {
this._newElements.push(element);
console.log("Element added");
this.RenderLayer(this._dataFromOverpass); // Update the layer
};
FilteredLayer.prototype.RenderLayer = function (data) {
var self = this;
if (this._geolayer !== undefined && this._geolayer !== null) {
this._map.map.removeLayer(this._geolayer);
}
this._dataFromOverpass = data;
var fusedFeatures = [];
var idsFromOverpass = [];
for (var _i = 0, _a = data.features; _i < _a.length; _i++) {
var feature = _a[_i];
idsFromOverpass.push(feature.properties.id);
fusedFeatures.push(feature);
}
for (var _b = 0, _c = this._newElements; _b < _c.length; _b++) {
var feature = _c[_b];
if (idsFromOverpass.indexOf(feature.properties.id) < 0) {
// This element is not yet uploaded or not yet visible in overpass
// We include it in the layer
fusedFeatures.push(feature);
}
}
// We use a new, fused dataset
data = {
type: "FeatureCollection",
features: fusedFeatures
};
// The data is split in two parts: the poinst and the rest
// The points get a special treatment in order to render them properly
// Note that some features might get a point representation as well
this._geolayer = leaflet_1.default.geoJSON(data, {
style: function (feature) {
return self._style(feature.properties);
},
pointToLayer: function (feature, latLng) {
var style = self._style(feature.properties);
var marker;
if (style.icon === undefined) {
marker = leaflet_1.default.circle(latLng, {
radius: 25,
color: style.color
});
}
else {
marker = leaflet_1.default.marker(latLng, {
icon: style.icon
});
}
return marker;
},
onEachFeature: function (feature, layer) {
var eventSource = self._storage.addOrGetElement(feature);
eventSource.addCallback(function () {
if (layer.setIcon) {
layer.setIcon(self._style(feature.properties).icon);
}
else {
console.log("UPdating", layer);
self._geolayer.setStyle(function (feature) {
return self._style(feature.properties);
});
}
});
layer.on("click", function (e) {
console.log("Selected ", feature);
self._selectedElement.setData(feature.properties);
var uiElement = self._showOnPopup(eventSource);
var popup = leaflet_1.default.popup()
.setContent(uiElement.Render())
.setLatLng(e.latlng)
.openOn(self._map.map);
uiElement.Update();
uiElement.Activate();
leaflet_1.default.DomEvent.stop(e); // Marks the event as consumed
});
}
});
if (this.isDisplayed.data) {
this._geolayer.addTo(this._map.map);
}
};
return FilteredLayer;
}());
exports.FilteredLayer = FilteredLayer;

View file

@ -1,117 +0,0 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeoLocationHandler = void 0;
var UIEventSource_1 = require("../UI/UIEventSource");
var UIElement_1 = require("../UI/UIElement");
var leaflet_1 = require("leaflet");
var Helpers_1 = require("../Helpers");
var GeoLocationHandler = /** @class */ (function (_super) {
__extends(GeoLocationHandler, _super);
function GeoLocationHandler(map) {
var _this = _super.call(this, undefined) || this;
_this.currentLocation = new UIEventSource_1.UIEventSource(undefined);
_this._isActive = new UIEventSource_1.UIEventSource(false);
_this._permission = new UIEventSource_1.UIEventSource("");
_this._map = map;
_this.ListenTo(_this.currentLocation);
_this.ListenTo(_this._isActive);
_this.ListenTo(_this._permission);
var self = _this;
function onAccuratePositionProgress(e) {
console.log(e.accuracy);
console.log(e.latlng);
self.currentLocation.setData({ latlng: e.latlng, accuracy: e.accuracy });
}
function onAccuratePositionFound(e) {
console.log(e.accuracy);
console.log(e.latlng);
self.currentLocation.setData({ latlng: e.latlng, accuracy: e.accuracy });
}
function onAccuratePositionError(e) {
console.log("onerror", e.message);
}
map.map.on('accuratepositionprogress', onAccuratePositionProgress);
map.map.on('accuratepositionfound', onAccuratePositionFound);
map.map.on('accuratepositionerror', onAccuratePositionError);
var icon = leaflet_1.default.icon({
iconUrl: './assets/crosshair-blue.svg',
iconSize: [40, 40],
iconAnchor: [20, 20],
});
_this.currentLocation.addCallback(function (location) {
var newMarker = leaflet_1.default.marker(location.latlng, { icon: icon });
newMarker.addTo(map.map);
if (self._marker !== undefined) {
map.map.removeLayer(self._marker);
}
self._marker = newMarker;
});
navigator.permissions.query({ name: 'geolocation' })
.then(function (status) {
console.log("Geolocation is already", status);
if (status.state === "granted") {
self.StartGeolocating();
}
self._permission.setData(status.state);
status.onchange = function () {
self._permission.setData(status.state);
};
});
_this.HideOnEmpty(true);
return _this;
}
GeoLocationHandler.prototype.InnerRender = function () {
if (this.currentLocation.data) {
return "<img src='./assets/crosshair-blue.svg' alt='locate me'>";
}
if (this._isActive.data) {
return "<img src='./assets/crosshair-blue-center.svg' alt='locate me'>";
}
return "<img src='./assets/crosshair.svg' alt='locate me'>";
};
GeoLocationHandler.prototype.StartGeolocating = function () {
var self = this;
if (self._permission.data === "denied") {
return "";
}
if (self.currentLocation.data !== undefined) {
self._map.map.flyTo(self.currentLocation.data.latlng, 18);
}
console.log("Searching location using GPS");
self._map.map.findAccuratePosition({
maxWait: 10000,
desiredAccuracy: 50 // defaults to 20
});
if (!self._isActive.data) {
self._isActive.setData(true);
Helpers_1.Helpers.DoEvery(60000, function () {
self._map.map.findAccuratePosition({
maxWait: 10000,
desiredAccuracy: 50 // defaults to 20
});
});
}
};
GeoLocationHandler.prototype.InnerUpdate = function (htmlElement) {
_super.prototype.InnerUpdate.call(this, htmlElement);
var self = this;
htmlElement.onclick = function () {
self.StartGeolocating();
};
};
return GeoLocationHandler;
}(UIElement_1.UIElement));
exports.GeoLocationHandler = GeoLocationHandler;

View file

@ -1,185 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeoOperations = void 0;
var turf = require("turf");
var GeoOperations = /** @class */ (function () {
function GeoOperations() {
}
GeoOperations.surfaceAreaInSqMeters = function (feature) {
return turf.area(feature);
};
GeoOperations.featureIsContainedInAny = function (feature, shouldNotContain, maxOverlapPercentage) {
// Returns 'false' if no problematic intersection is found
if (feature.geometry.type === "Point") {
var coor = feature.geometry.coordinates;
for (var _i = 0, shouldNotContain_1 = shouldNotContain; _i < shouldNotContain_1.length; _i++) {
var shouldNotContainElement = shouldNotContain_1[_i];
var shouldNotContainBBox = BBox.get(shouldNotContainElement);
var featureBBox = BBox.get(feature);
if (!featureBBox.overlapsWith(shouldNotContainBBox)) {
continue;
}
if (this.inside(coor, shouldNotContainElement)) {
return true;
}
}
return false;
}
if (feature.geometry.type === "Polygon" || feature.geometry.type === "MultiPolygon") {
var poly = feature;
var featureBBox = BBox.get(feature);
var featureSurface = GeoOperations.surfaceAreaInSqMeters(poly);
for (var _a = 0, shouldNotContain_2 = shouldNotContain; _a < shouldNotContain_2.length; _a++) {
var shouldNotContainElement = shouldNotContain_2[_a];
var shouldNotContainBBox = BBox.get(shouldNotContainElement);
var overlaps = featureBBox.overlapsWith(shouldNotContainBBox);
if (!overlaps) {
continue;
}
// Calculate the surface area of the intersection
// If it is too big, refuse
try {
var intersection = turf.intersect(poly, shouldNotContainElement);
if (intersection == null) {
continue;
}
var intersectionSize = turf.area(intersection);
var ratio = intersectionSize / featureSurface;
if (ratio * 100 >= maxOverlapPercentage) {
console.log("Refused", poly.id, " due to ", shouldNotContainElement.id, "intersection ratio is ", ratio, "which is bigger then the target ratio of ", (maxOverlapPercentage / 100));
return true;
}
}
catch (exception) {
console.log("EXCEPTION CAUGHT WHILE INTERSECTING: ", exception);
// We assume that this failed due to an intersection
return true;
}
}
return false; // No problematic intersections found
}
return false;
};
/**
* Simple check: that every point of the polygon is inside the container
* @param polygon
* @param container
*/
GeoOperations.isPolygonInside = function (polygon, container) {
for (var _i = 0, _a = polygon.geometry.coordinates[0]; _i < _a.length; _i++) {
var coor = _a[_i];
if (!GeoOperations.inside(coor, container)) {
return false;
}
}
return true;
};
/**
* Simple check: one point of the polygon is inside the container
* @param polygon
* @param container
*/
GeoOperations.isPolygonTouching = function (polygon, container) {
for (var _i = 0, _a = polygon.geometry.coordinates[0]; _i < _a.length; _i++) {
var coor = _a[_i];
if (GeoOperations.inside(coor, container)) {
return true;
}
}
return false;
};
GeoOperations.inside = function (pointCoordinate, feature) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
if (feature.geometry.type === "Point") {
return false;
}
var x = pointCoordinate[0];
var y = pointCoordinate[1];
var poly = feature.geometry.coordinates[0];
var inside = false;
for (var i = 0, j = poly.length - 1; i < poly.length; j = i++) {
var coori = poly[i];
var coorj = poly[j];
var xi = coori[0];
var yi = coori[1];
var xj = coorj[0];
var yj = coorj[1];
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) {
inside = !inside;
}
}
return inside;
};
;
return GeoOperations;
}());
exports.GeoOperations = GeoOperations;
var BBox = /** @class */ (function () {
function BBox(coordinates) {
this.maxLat = Number.MIN_VALUE;
this.maxLon = Number.MIN_VALUE;
this.minLat = Number.MAX_VALUE;
this.minLon = Number.MAX_VALUE;
for (var _i = 0, coordinates_1 = coordinates; _i < coordinates_1.length; _i++) {
var coordinate = coordinates_1[_i];
this.maxLon = Math.max(this.maxLon, coordinate[0]);
this.maxLat = Math.max(this.maxLat, coordinate[1]);
this.minLon = Math.min(this.minLon, coordinate[0]);
this.minLat = Math.min(this.minLat, coordinate[1]);
}
this.check();
}
BBox.prototype.check = function () {
if (isNaN(this.maxLon) || isNaN(this.maxLat) || isNaN(this.minLon) || isNaN(this.minLat)) {
console.log(this);
throw "BBOX has NAN";
}
};
BBox.prototype.overlapsWith = function (other) {
this.check();
other.check();
if (this.maxLon < other.minLon) {
return false;
}
if (this.maxLat < other.minLat) {
return false;
}
if (this.minLon > other.maxLon) {
return false;
}
if (this.minLat > other.maxLat) {
return false;
}
return true;
};
BBox.get = function (feature) {
if (feature.bbox === undefined) {
if (feature.geometry.type === "MultiPolygon") {
var coordinates = [];
for (var _i = 0, _a = feature.geometry.coordinates; _i < _a.length; _i++) {
var coorlist = _a[_i];
coordinates = coordinates.concat(coorlist[0]);
}
feature.bbox = new BBox(coordinates);
}
else if (feature.geometry.type === "Polygon") {
feature.bbox = new BBox(feature.geometry.coordinates[0]);
}
else if (feature.geometry.type === "LineString") {
feature.bbox = new BBox(feature.geometry.coordinates);
}
else if (feature.geometry.type === "Point") {
// Point
feature.bbox = new BBox([feature.geometry.coordinates]);
}
else {
throw "Cannot calculate bbox, unknown type " + feature.geometry.type;
}
}
return feature.bbox;
};
return BBox;
}());

View file

@ -1,22 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Geocoding = void 0;
var $ = require("jquery");
var Geocoding = /** @class */ (function () {
function Geocoding() {
}
Geocoding.Search = function (query, basemap, handleResult, onFail) {
var b = basemap.map.getBounds();
console.log(b);
$.getJSON(Geocoding.host + "format=json&limit=1&viewbox=" +
(b.getEast() + "," + b.getNorth() + "," + b.getWest() + "," + b.getSouth()) +
"&accept-language=nl&q=" + query, function (data) {
handleResult(data);
}).fail(function () {
onFail();
});
};
Geocoding.host = "https://nominatim.openstreetmap.org/search?";
return Geocoding;
}());
exports.Geocoding = Geocoding;

View file

@ -1,185 +0,0 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImageSearcher = void 0;
var UIEventSource_1 = require("../UI/UIEventSource");
var Wikimedia_1 = require("./Wikimedia");
var WikimediaImage_1 = require("../UI/Image/WikimediaImage");
var SimpleImageElement_1 = require("../UI/Image/SimpleImageElement");
var ImgurImage_1 = require("../UI/Image/ImgurImage");
/**
* There are multiple way to fetch images for an object
* 1) There is an image tag
* 2) There is an image tag, the image tag contains multiple ';'-seperated URLS
* 3) there are multiple image tags, e.g. 'image', 'image:0', 'image:1', and 'image_0', 'image_1' - however, these are pretty rare so we are gonna ignore them
* 4) There is a wikimedia_commons-tag, which either has a 'File': or a 'category:' containing images
* 5) There is a wikidata-tag, and the wikidata item either has an 'image' attribute or has 'a link to a wikimedia commons category'
* 6) There is a wikipedia article, from which we can deduct the wikidata item
*
* For some images, author and license should be shown
*/
/**
* Class which search for all the possible locations for images and which builds a list of UI-elements for it.
* Note that this list is embedded into an UIEVentSource, ready to put it into a carousel
*/
var ImageSearcher = /** @class */ (function (_super) {
__extends(ImageSearcher, _super);
function ImageSearcher(tags, changes) {
var _this = _super.call(this, []) || this;
_this._wdItem = new UIEventSource_1.UIEventSource("");
_this._commons = new UIEventSource_1.UIEventSource("");
_this._activated = false;
_this._deletedImages = new UIEventSource_1.UIEventSource([]);
_this._tags = tags;
_this._changes = changes;
var self = _this;
_this._wdItem.addCallback(function () {
// Load the wikidata item, then detect usage on 'commons'
var wikidataId = self._wdItem.data;
// @ts-ignore
if (wikidataId.startsWith("Q")) {
wikidataId = wikidataId.substr(1);
}
Wikimedia_1.Wikimedia.GetWikiData(parseInt(wikidataId), function (wd) {
self.AddImage(wd.image);
Wikimedia_1.Wikimedia.GetCategoryFiles(wd.commonsWiki, function (images) {
for (var _i = 0, _a = images.images; _i < _a.length; _i++) {
var image = _a[_i];
// @ts-ignore
if (image.startsWith("File:")) {
self.AddImage(image);
}
}
});
});
});
_this._commons.addCallback(function () {
var commons = self._commons.data;
// @ts-ignore
if (commons.startsWith("Category:")) {
Wikimedia_1.Wikimedia.GetCategoryFiles(commons, function (images) {
for (var _i = 0, _a = images.images; _i < _a.length; _i++) {
var image = _a[_i];
// @ts-ignore
if (image.startsWith("File:")) {
self.AddImage(image);
}
}
});
}
else { // @ts-ignore
if (commons.startsWith("File:")) {
self.AddImage(commons);
}
}
});
return _this;
}
ImageSearcher.prototype.AddImage = function (url) {
if (url === undefined || url === null || url === "") {
return;
}
for (var _i = 0, _a = this.data; _i < _a.length; _i++) {
var el = _a[_i];
if (el === url) {
return;
}
}
this.data.push(url);
this.ping();
};
ImageSearcher.prototype.ImageKey = function (url) {
var tgs = this._tags.data;
for (var key in tgs) {
if (tgs[key] === url) {
return key;
}
}
return undefined;
};
ImageSearcher.prototype.IsDeletable = function (url) {
return this.ImageKey(url) !== undefined;
};
ImageSearcher.prototype.Delete = function (url) {
var key = this.ImageKey(url);
if (key === undefined) {
return;
}
console.log("Deleting image...", key, " --> ", url);
this._changes.addChange(this._tags.data.id, key, "");
this._deletedImages.data.push(url);
this._deletedImages.ping();
};
ImageSearcher.prototype.Activate = function () {
if (this._activated) {
return;
}
this._activated = true;
this.LoadImages();
var self = this;
this._tags.addCallback(function () { return self.LoadImages(); });
};
ImageSearcher.prototype.LoadImages = function () {
if (!this._activated) {
return;
}
var imageTag = this._tags.data.image;
if (imageTag !== undefined) {
var bareImages = imageTag.split(";");
for (var _i = 0, bareImages_1 = bareImages; _i < bareImages_1.length; _i++) {
var bareImage = bareImages_1[_i];
this.AddImage(bareImage);
}
}
for (var key in this._tags.data) {
// @ts-ignore
if (key.startsWith("image:")) {
var url = this._tags.data[key];
this.AddImage(url);
}
}
var wdItem = this._tags.data.wikidata;
if (wdItem !== undefined) {
this._wdItem.setData(wdItem);
}
var commons = this._tags.data.wikimedia_commons;
if (commons !== undefined) {
this._commons.setData(commons);
}
};
/***
* Creates either a 'simpleimage' or a 'wikimediaimage' based on the string
* @param url
* @constructor
*/
ImageSearcher.CreateImageElement = function (url) {
// @ts-ignore
if (url.startsWith("File:")) {
return new WikimediaImage_1.WikimediaImage(url);
}
else if (url.startsWith("https://commons.wikimedia.org/wiki/")) {
var commons = url.substr("https://commons.wikimedia.org/wiki/".length);
return new WikimediaImage_1.WikimediaImage(commons);
}
else if (url.startsWith("https://i.imgur.com/")) {
return new ImgurImage_1.ImgurImage(url);
}
else {
return new SimpleImageElement_1.SimpleImageElement(new UIEventSource_1.UIEventSource(url));
}
};
return ImageSearcher;
}(UIEventSource_1.UIEventSource));
exports.ImageSearcher = ImageSearcher;

View file

@ -1,90 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Imgur = void 0;
var jquery_1 = require("jquery");
var Wikimedia_1 = require("./Wikimedia");
var Imgur = /** @class */ (function () {
function Imgur() {
}
Imgur.uploadMultiple = function (title, description, blobs, handleSuccessfullUpload, allDone, offset) {
if (offset === void 0) { offset = 0; }
if (blobs.length == offset) {
allDone();
return;
}
var blob = blobs.item(offset);
var self = this;
this.uploadImage(title, description, blob, function (imageUrl) {
handleSuccessfullUpload(imageUrl);
self.uploadMultiple(title, description, blobs, handleSuccessfullUpload, allDone, offset + 1);
});
};
Imgur.getDescriptionOfImage = function (url, handleDescription) {
var hash = url.substr("https://i.imgur.com/".length).split(".jpg")[0];
var apiUrl = 'https://api.imgur.com/3/image/' + hash;
var apiKey = '7070e7167f0a25a';
var settings = {
async: true,
crossDomain: true,
processData: false,
contentType: false,
type: 'GET',
url: apiUrl,
headers: {
Authorization: 'Client-ID ' + apiKey,
Accept: 'application/json',
},
};
jquery_1.default.ajax(settings).done(function (response) {
var descr = response.data.description;
var data = {};
for (var _i = 0, _a = descr.split("\n"); _i < _a.length; _i++) {
var tag = _a[_i];
var kv = tag.split(":");
var k = kv[0];
var v = kv[1].replace("\r", "");
data[k] = v;
}
console.log(data);
var licenseInfo = new Wikimedia_1.LicenseInfo();
licenseInfo.licenseShortName = data.license;
licenseInfo.artist = data.author;
handleDescription(licenseInfo);
}).fail(function (reason) {
console.log("Getting metadata from to IMGUR failed", reason);
});
};
Imgur.uploadImage = function (title, description, blob, handleSuccessfullUpload) {
var apiUrl = 'https://api.imgur.com/3/image';
var apiKey = '7070e7167f0a25a';
var settings = {
async: true,
crossDomain: true,
processData: false,
contentType: false,
type: 'POST',
url: apiUrl,
headers: {
Authorization: 'Client-ID ' + apiKey,
Accept: 'application/json',
},
mimeType: 'multipart/form-data',
};
var formData = new FormData();
formData.append('image', blob);
formData.append("title", title);
formData.append("description", description);
// @ts-ignore
settings.data = formData;
// Response contains stringified JSON
// Image URL available at response.data.link
jquery_1.default.ajax(settings).done(function (response) {
response = JSON.parse(response);
handleSuccessfullUpload(response.data.link);
}).fail(function (reason) {
console.log("Uploading to IMGUR failed", reason);
});
};
return Imgur;
}());
exports.Imgur = Imgur;

View file

@ -1,99 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LayerUpdater = void 0;
var Overpass_1 = require("./Overpass");
var TagsFilter_1 = require("./TagsFilter");
var UIEventSource_1 = require("../UI/UIEventSource");
var LayerUpdater = /** @class */ (function () {
/**
* The most important layer should go first, as that one gets first pick for the questions
* @param map
* @param minzoom
* @param layers
*/
function LayerUpdater(map, minzoom, layers) {
this.runningQuery = new UIEventSource_1.UIEventSource(false);
this._map = map;
this._layers = layers;
this._minzoom = minzoom;
var filters = [];
for (var _i = 0, layers_1 = layers; _i < layers_1.length; _i++) {
var layer = layers_1[_i];
filters.push(layer.filters);
}
this._overpass = new Overpass_1.Overpass(new TagsFilter_1.Or(filters));
var self = this;
map.Location.addCallback(function () {
self.update();
});
}
LayerUpdater.prototype.handleData = function (geojson) {
this.runningQuery.setData(false);
for (var _i = 0, _a = this._layers; _i < _a.length; _i++) {
var layer = _a[_i];
geojson = layer.SetApplicableData(geojson);
}
if (geojson.features.length > 0) {
console.log("Got some leftovers: ", geojson);
}
};
LayerUpdater.prototype.handleFail = function (reason) {
console.log("QUERY FAILED", reason);
console.log("Retrying in 1s");
this.previousBounds = undefined;
var self = this;
window.setTimeout(function () { self.update(); }, 1000);
};
LayerUpdater.prototype.update = function () {
if (this.IsInBounds()) {
return;
}
console.log("Zoom level: ", this._map.map.getZoom(), "Least needed zoom:", this._minzoom);
if (this._map.map.getZoom() < this._minzoom || this._map.Location.data.zoom < this._minzoom) {
console.log("Not running query: zoom not sufficient");
return;
}
if (this.runningQuery.data) {
console.log("Still running a query, skip");
}
var bbox = this.buildBboxFor();
this.runningQuery.setData(true);
var self = this;
this._overpass.queryGeoJson(bbox, function (data) {
self.handleData(data);
}, function (reason) {
self.handleFail(reason);
});
};
LayerUpdater.prototype.buildBboxFor = function () {
var b = this._map.map.getBounds();
var diff = 0.07;
var n = b.getNorth() + diff;
var e = b.getEast() + diff;
var s = b.getSouth() - diff;
var w = b.getWest() - diff;
this.previousBounds = { north: n, east: e, south: s, west: w };
return "[bbox:" + s + "," + w + "," + n + "," + e + "]";
};
LayerUpdater.prototype.IsInBounds = function () {
if (this.previousBounds === undefined) {
return false;
}
var b = this._map.map.getBounds();
if (b.getSouth() < this.previousBounds.south) {
return false;
}
if (b.getNorth() > this.previousBounds.north) {
return false;
}
if (b.getEast() > this.previousBounds.east) {
return false;
}
if (b.getWest() < this.previousBounds.west) {
return false;
}
return true;
};
return LayerUpdater;
}());
exports.LayerUpdater = LayerUpdater;

View file

@ -1,256 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OsmConnection = exports.UserDetails = void 0;
// @ts-ignore
var osm_auth_1 = require("osm-auth");
var UIEventSource_1 = require("../UI/UIEventSource");
var UserDetails = /** @class */ (function () {
function UserDetails() {
this.loggedIn = false;
this.name = "Not logged in";
this.csCount = 0;
this.unreadMessages = 0;
this.totalMessages = 0;
}
return UserDetails;
}());
exports.UserDetails = UserDetails;
var OsmConnection = /** @class */ (function () {
function OsmConnection(dryRun) {
this.auth = new osm_auth_1.default({
oauth_consumer_key: 'hivV7ec2o49Two8g9h8Is1VIiVOgxQ1iYexCbvem',
oauth_secret: 'wDBRTCem0vxD7txrg1y6p5r8nvmz8tAhET7zDASI',
auto: true // show a login form if the user is not authenticated and
// you try to do a call
});
this.preferences = new UIEventSource_1.UIEventSource({});
this.preferenceSources = {};
this.userDetails = new UIEventSource_1.UIEventSource(new UserDetails());
this.userDetails.data.osmConnection = this;
this.userDetails.data.dryRun = dryRun;
this._dryRun = dryRun;
if (this.auth.authenticated()) {
this.AttemptLogin(); // Also updates the user badge
}
else {
console.log("Not authenticated");
}
if (dryRun) {
console.log("DRYRUN ENABLED");
}
}
OsmConnection.prototype.LogOut = function () {
this.auth.logout();
this.userDetails.data.loggedIn = false;
this.userDetails.ping();
console.log("Logged out");
};
OsmConnection.prototype.AttemptLogin = function () {
var self = this;
this.auth.xhr({
method: 'GET',
path: '/api/0.6/user/details'
}, function (err, details) {
var _a;
if (err != null) {
console.log(err);
self.auth.logout();
self.userDetails.data.loggedIn = false;
self.userDetails.ping();
}
if (details == null) {
return;
}
self.UpdatePreferences();
// details is an XML DOM of user details
var userInfo = details.getElementsByTagName("user")[0];
// let moreDetails = new DOMParser().parseFromString(userInfo.innerHTML, "text/xml");
var data = self.userDetails.data;
data.loggedIn = true;
console.log("Login completed, userinfo is ", userInfo);
data.name = userInfo.getAttribute('display_name');
data.csCount = userInfo.getElementsByTagName("changesets")[0].getAttribute("count");
data.img = undefined;
var imgEl = userInfo.getElementsByTagName("img");
if (imgEl !== undefined && imgEl[0] !== undefined) {
data.img = imgEl[0].getAttribute("href");
}
data.img = (_a = data.img) !== null && _a !== void 0 ? _a : "./assets/osm-logo.svg";
var homeEl = userInfo.getElementsByTagName("home");
if (homeEl !== undefined && homeEl[0] !== undefined) {
var lat = parseFloat(homeEl[0].getAttribute("lat"));
var lon = parseFloat(homeEl[0].getAttribute("lon"));
data.home = { lat: lat, lon: lon };
}
var messages = userInfo.getElementsByTagName("messages")[0].getElementsByTagName("received")[0];
data.unreadMessages = parseInt(messages.getAttribute("unread"));
data.totalMessages = parseInt(messages.getAttribute("count"));
self.userDetails.ping();
});
};
/**
* All elements with class 'activate-osm-authentication' are loaded and get an 'onclick' to authenticate
*/
OsmConnection.prototype.registerActivateOsmAUthenticationClass = function () {
var self = this;
var authElements = document.getElementsByClassName("activate-osm-authentication");
for (var i = 0; i < authElements.length; i++) {
var element = authElements.item(i);
// @ts-ignore
element.onclick = function () {
self.AttemptLogin();
};
}
};
OsmConnection.prototype.GetPreference = function (key) {
var _this = this;
if (this.preferenceSources[key] !== undefined) {
return this.preferenceSources[key];
}
if (this.userDetails.data.loggedIn) {
this.UpdatePreferences();
}
var pref = new UIEventSource_1.UIEventSource(this.preferences.data[key]);
pref.addCallback(function (v) {
_this.SetPreference(key, v);
});
this.preferences.addCallback(function (prefs) {
if (prefs[key] !== undefined) {
pref.setData(prefs[key]);
}
});
this.preferenceSources[key] = pref;
return pref;
};
OsmConnection.prototype.UpdatePreferences = function () {
var self = this;
this.auth.xhr({
method: 'GET',
path: '/api/0.6/user/preferences'
}, function (error, value) {
if (error) {
console.log("Could not load preferences", error);
return;
}
var prefs = value.getElementsByTagName("preference");
for (var i = 0; i < prefs.length; i++) {
var pref = prefs[i];
var k = pref.getAttribute("k");
var v = pref.getAttribute("v");
self.preferences.data[k] = v;
}
self.preferences.ping();
});
};
OsmConnection.prototype.SetPreference = function (k, v) {
if (!this.userDetails.data.loggedIn) {
console.log("Not saving preference: user not logged in");
return;
}
if (this.preferences.data[k] === v) {
console.log("Not updating preference", k, " to ", v, "not changed");
return;
}
console.log("Updating preference", k, " to ", v);
this.preferences.data[k] = v;
this.preferences.ping();
this.auth.xhr({
method: 'PUT',
path: '/api/0.6/user/preferences/' + k,
options: { header: { 'Content-Type': 'text/plain' } },
content: v
}, function (error, result) {
if (error) {
console.log("Could not set preference", error);
return;
}
console.log("Preference written!", result == "" ? "OK" : result);
});
};
OsmConnection.parseUploadChangesetResponse = function (response) {
var nodes = response.getElementsByTagName("node");
var mapping = {};
// @ts-ignore
for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
var node = nodes_1[_i];
var oldId = parseInt(node.attributes.old_id.value);
var newId = parseInt(node.attributes.new_id.value);
if (oldId !== undefined && newId !== undefined &&
!isNaN(oldId) && !isNaN(newId)) {
mapping["node/" + oldId] = "node/" + newId;
}
}
return mapping;
};
OsmConnection.prototype.UploadChangeset = function (comment, generateChangeXML, handleMapping, continuation) {
if (this._dryRun) {
console.log("NOT UPLOADING as dryrun is true");
var changesetXML = generateChangeXML("123456");
console.log(changesetXML);
continuation();
return;
}
var self = this;
this.OpenChangeset(comment, function (csId) {
var changesetXML = generateChangeXML(csId);
self.AddChange(csId, changesetXML, function (csId, mapping) {
self.CloseChangeset(csId, continuation);
handleMapping(mapping);
});
});
this.userDetails.data.csCount++;
this.userDetails.ping();
};
OsmConnection.prototype.OpenChangeset = function (comment, continuation) {
this.auth.xhr({
method: 'PUT',
path: '/api/0.6/changeset/create',
options: { header: { 'Content-Type': 'text/xml' } },
content: '<osm><changeset>' +
'<tag k="created_by" v="MapComplete 0.0.0" />' +
'<tag k="comment" v="' + comment + '"/>' +
'</changeset></osm>'
}, function (err, response) {
if (response === undefined) {
console.log("err", err);
return;
}
else {
continuation(response);
}
});
};
OsmConnection.prototype.AddChange = function (changesetId, changesetXML, continuation) {
this.auth.xhr({
method: 'POST',
options: { header: { 'Content-Type': 'text/xml' } },
path: '/api/0.6/changeset/' + changesetId + '/upload',
content: changesetXML
}, function (err, response) {
if (response == null) {
console.log("err", err);
return;
}
var mapping = OsmConnection.parseUploadChangesetResponse(response);
console.log("Uplaoded changeset ", changesetId);
continuation(changesetId, mapping);
});
};
OsmConnection.prototype.CloseChangeset = function (changesetId, continuation) {
console.log("closing");
this.auth.xhr({
method: 'PUT',
path: '/api/0.6/changeset/' + changesetId + '/close',
}, function (err, response) {
if (response == null) {
console.log("err", err);
}
console.log("Closed changeset ", changesetId);
if (continuation !== undefined) {
continuation();
}
});
};
return OsmConnection;
}());
exports.OsmConnection = OsmConnection;

View file

@ -1,56 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OsmImageUploadHandler = void 0;
var ImageUploadFlow_1 = require("../UI/ImageUploadFlow");
var OsmImageUploadHandler = /** @class */ (function () {
function OsmImageUploadHandler(tags, userdetails, preferedLicense, changeHandler, slideShow) {
this._slideShow = slideShow; // To move the slideshow (if any) to the last, just added element
if (tags === undefined || userdetails === undefined || changeHandler === undefined) {
throw "Something is undefined";
}
this._tags = tags;
this._changeHandler = changeHandler;
this._userdetails = userdetails;
this._preferedLicense = preferedLicense;
}
OsmImageUploadHandler.prototype.generateOptions = function (license) {
var _a;
var tags = this._tags.data;
var self = this;
var title = (_a = tags.name) !== null && _a !== void 0 ? _a : "Unknown area";
var description = [
"author:" + this._userdetails.data.name,
"license:" + license,
"wikidata:" + tags.wikidata,
"osmid:" + tags.id,
"name:" + tags.name
].join("\n");
var changes = this._changeHandler;
return {
title: title,
description: description,
handleURL: function (url) {
var freeIndex = 0;
while (tags["image:" + freeIndex] !== undefined) {
freeIndex++;
}
console.log("Adding image:" + freeIndex, url);
changes.addChange(tags.id, "image:" + freeIndex, url);
self._slideShow.MoveTo(-1); // set the last (thus newly added) image) to view
},
allDone: function () {
changes.uploadAll(function () {
console.log("Writing changes...");
});
}
};
};
OsmImageUploadHandler.prototype.getUI = function () {
var self = this;
return new ImageUploadFlow_1.ImageUploadFlow(this._userdetails, this._preferedLicense, function (license) {
return self.generateOptions(license);
});
};
return OsmImageUploadHandler;
}());
exports.OsmImageUploadHandler = OsmImageUploadHandler;

View file

@ -1,160 +0,0 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.OsmRelation = exports.OsmWay = exports.OsmNode = exports.OsmObject = void 0;
var $ = require("jquery");
var OsmObject = /** @class */ (function () {
function OsmObject(type, id) {
this.tags = {};
this.changed = false;
this.id = id;
this.type = type;
}
OsmObject.DownloadObject = function (id, continuation) {
var splitted = id.split("/");
var type = splitted[0];
var idN = splitted[1];
switch (type) {
case ("node"):
return new OsmNode(idN).Download(continuation);
case ("way"):
return new OsmWay(idN).Download(continuation);
case ("relation"):
return new OsmRelation(idN).Download(continuation);
}
};
/**
* Replaces all '"' (double quotes) by '&quot;'
* Bugfix where names containing '"' were not uploaded, such as '"Het Zwin" nature reserve'
* @param string
* @constructor
*/
OsmObject.prototype.Escape = function (string) {
while (string.indexOf('"') >= 0) {
string = string.replace('"', '&quot;');
}
return string;
};
/**
* Generates the changeset-XML for tags
* @constructor
*/
OsmObject.prototype.TagsXML = function () {
var tags = "";
for (var key in this.tags) {
var v = this.tags[key];
if (v !== "") {
tags += ' <tag k="' + this.Escape(key) + '" v="' + this.Escape(this.tags[key]) + '"/>\n';
}
}
return tags;
};
OsmObject.prototype.Download = function (continuation) {
var self = this;
$.getJSON("https://www.openstreetmap.org/api/0.6/" + this.type + "/" + this.id, function (data) {
var element = data.elements[0];
self.tags = element.tags;
self.version = element.version;
self.SaveExtraData(element);
continuation(self);
});
return this;
};
OsmObject.prototype.addTag = function (k, v) {
if (k in this.tags) {
var oldV = this.tags[k];
if (oldV == v) {
return;
}
console.log("WARNING: overwriting ", oldV, " with ", v, " for key ", k);
}
this.tags[k] = v;
this.changed = true;
};
OsmObject.prototype.VersionXML = function () {
if (this.version === undefined) {
return "";
}
return 'version="' + this.version + '"';
};
return OsmObject;
}());
exports.OsmObject = OsmObject;
var OsmNode = /** @class */ (function (_super) {
__extends(OsmNode, _super);
function OsmNode(id) {
return _super.call(this, "node", id) || this;
}
OsmNode.prototype.ChangesetXML = function (changesetId) {
var tags = this.TagsXML();
var change = ' <node id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + ' lat="' + this.lat + '" lon="' + this.lon + '">\n' +
tags +
' </node>\n';
return change;
};
OsmNode.prototype.SaveExtraData = function (element) {
this.lat = element.lat;
this.lon = element.lon;
};
return OsmNode;
}(OsmObject));
exports.OsmNode = OsmNode;
var OsmWay = /** @class */ (function (_super) {
__extends(OsmWay, _super);
function OsmWay(id) {
return _super.call(this, "way", id) || this;
}
OsmWay.prototype.ChangesetXML = function (changesetId) {
var tags = this.TagsXML();
var nds = "";
for (var node in this.nodes) {
nds += ' <nd ref="' + this.nodes[node] + '"/>\n';
}
var change = ' <way id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + '>\n' +
nds +
tags +
' </way>\n';
return change;
};
OsmWay.prototype.SaveExtraData = function (element) {
this.nodes = element.nodes;
};
return OsmWay;
}(OsmObject));
exports.OsmWay = OsmWay;
var OsmRelation = /** @class */ (function (_super) {
__extends(OsmRelation, _super);
function OsmRelation(id) {
return _super.call(this, "relation", id) || this;
}
OsmRelation.prototype.ChangesetXML = function (changesetId) {
var members = "";
for (var memberI in this.members) {
var member = this.members[memberI];
members += ' <member type="' + member.type + '" ref="' + member.ref + '" role="' + member.role + '"/>\n';
}
var tags = this.TagsXML();
var change = ' <relation id="' + this.id + '" changeset="' + changesetId + '" ' + this.VersionXML() + '>\n' +
members +
tags +
' </relation>\n';
return change;
};
OsmRelation.prototype.SaveExtraData = function (element) {
this.members = element.members;
};
return OsmRelation;
}(OsmObject));
exports.OsmRelation = OsmRelation;

View file

@ -1,47 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Overpass = void 0;
var OsmToGeoJson = require("osmtogeojson");
var $ = require("jquery");
/**
* Interfaces overpass to get all the latest data
*/
var Overpass = /** @class */ (function () {
function Overpass(filter) {
this._filter = filter;
}
Overpass.prototype.buildQuery = function (bbox) {
var filters = this._filter.asOverpass();
var filter = "";
for (var _i = 0, filters_1 = filters; _i < filters_1.length; _i++) {
var filterOr = filters_1[_i];
filter += 'nwr' + filterOr + ';';
}
var query = '[out:json][timeout:25]' + bbox + ';(' + filter + ');out body;>;out skel qt;';
console.log(query);
return "https://overpass-api.de/api/interpreter?data=" + encodeURIComponent(query);
};
Overpass.prototype.queryGeoJson = function (bbox, continuation, onFail) {
var query = this.buildQuery(bbox);
if (Overpass.testUrl !== null) {
console.log("Using testing URL");
query = Overpass.testUrl;
}
$.getJSON(query, function (json, status) {
if (status !== "success") {
console.log("Query failed");
onFail(status);
}
if (json.elements === [] && json.remarks.indexOf("runtime error") > 0) {
console.log("Timeout or other runtime error");
return;
}
// @ts-ignore
var geojson = OsmToGeoJson.default(json);
continuation(geojson);
}).fail(onFail);
};
Overpass.testUrl = null;
return Overpass;
}());
exports.Overpass = Overpass;

View file

@ -32,7 +32,7 @@ export class Overpass {
queryGeoJson(bbox: string, continuation: ((any) => void), onFail: ((reason) => void)): void { queryGeoJson(bbox: string, continuation: ((any) => void), onFail: ((reason) => void)): void {
let query = this.buildQuery(bbox); let query = this.buildQuery(bbox);
if(Overpass.testUrl !== null){ if(Overpass.testUrl !== null){
console.log("Using testing URL") console.log("Using testing URL")
query = Overpass.testUrl; query = Overpass.testUrl;
@ -44,7 +44,7 @@ export class Overpass {
console.log("Query failed") console.log("Query failed")
onFail(status); onFail(status);
} }
if(json.elements === [] && json.remarks.indexOf("runtime error") > 0){ if(json.elements === [] && json.remarks.indexOf("runtime error") > 0){
console.log("Timeout or other runtime error"); console.log("Timeout or other runtime error");
return; return;

View file

@ -1,42 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StrayClickHandler = void 0;
var leaflet_1 = require("leaflet");
/**
* The stray-click-hanlders adds a marker to the map if no feature was clicked.
* Shows the given uiToShow-element in the messagebox
*/
var StrayClickHandler = /** @class */ (function () {
function StrayClickHandler(basemap, selectElement, leftMessage, uiToShow) {
var _this = this;
this._basemap = basemap;
this._leftMessage = leftMessage;
this._uiToShow = uiToShow;
var self = this;
var map = basemap.map;
basemap.LastClickLocation.addCallback(function (lastClick) {
selectElement.setData(undefined);
if (self._lastMarker !== undefined) {
map.removeLayer(self._lastMarker);
}
self._lastMarker = leaflet_1.default.marker([lastClick.lat, lastClick.lon]);
var uiElement = uiToShow();
var popup = leaflet_1.default.popup().setContent(uiElement.Render());
uiElement.Activate();
uiElement.Update();
self._lastMarker.addTo(map);
self._lastMarker.bindPopup(popup).openPopup();
self._lastMarker.on("click", function () {
leftMessage.setData(self._uiToShow);
});
});
selectElement.addCallback(function () {
if (self._lastMarker !== undefined) {
map.removeLayer(self._lastMarker);
_this._lastMarker = undefined;
}
});
}
return StrayClickHandler;
}());
exports.StrayClickHandler = StrayClickHandler;

View file

@ -1,240 +0,0 @@
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TagUtils = exports.Not = exports.And = exports.Or = exports.Tag = exports.Regex = exports.TagsFilter = void 0;
var TagsFilter = /** @class */ (function () {
function TagsFilter() {
}
TagsFilter.prototype.matchesProperties = function (properties) {
return this.matches(TagUtils.proprtiesToKV(properties));
};
return TagsFilter;
}());
exports.TagsFilter = TagsFilter;
var Regex = /** @class */ (function (_super) {
__extends(Regex, _super);
function Regex(k, r) {
var _this = _super.call(this) || this;
_this._k = k;
_this._r = r;
return _this;
}
Regex.prototype.asOverpass = function () {
return ["['" + this._k + "'~'" + this._r + "']"];
};
Regex.prototype.matches = function (tags) {
var _a;
if (!(tags instanceof Array)) {
throw "You used 'matches' on something that is not a list. Did you mean to use 'matchesProperties'?";
}
for (var _i = 0, tags_1 = tags; _i < tags_1.length; _i++) {
var tag = tags_1[_i];
if (tag.k === this._k) {
if (tag.v === "") {
// This tag has been removed
return false;
}
if (this._r === "*") {
// Any is allowed
return true;
}
var matchCount = (_a = tag.v.match(this._r)) === null || _a === void 0 ? void 0 : _a.length;
return (matchCount !== null && matchCount !== void 0 ? matchCount : 0) > 0;
}
}
return false;
};
Regex.prototype.substituteValues = function (tags) {
throw "Substituting values is not supported on regex tags";
};
return Regex;
}(TagsFilter));
exports.Regex = Regex;
var Tag = /** @class */ (function (_super) {
__extends(Tag, _super);
function Tag(key, value) {
var _this = _super.call(this) || this;
_this.key = key;
_this.value = value;
return _this;
}
Tag.prototype.matches = function (tags) {
for (var _i = 0, tags_2 = tags; _i < tags_2.length; _i++) {
var tag = tags_2[_i];
if (tag.k === this.key) {
if (tag.v === "") {
// This tag has been removed
return this.value === "";
}
if (this.value === "*") {
// Any is allowed
return true;
}
return this.value === tag.v;
}
}
if (this.value === "") {
return true;
}
return false;
};
Tag.prototype.asOverpass = function () {
if (this.value === "*") {
return ['["' + this.key + '"]'];
}
if (this.value === "") {
// NOT having this key
return ['[!"' + this.key + '"]'];
}
return ['["' + this.key + '"="' + this.value + '"]'];
};
Tag.prototype.substituteValues = function (tags) {
return new Tag(this.key, TagUtils.ApplyTemplate(this.value, tags));
};
return Tag;
}(TagsFilter));
exports.Tag = Tag;
var Or = /** @class */ (function (_super) {
__extends(Or, _super);
function Or(or) {
var _this = _super.call(this) || this;
_this.or = or;
return _this;
}
Or.prototype.matches = function (tags) {
for (var _i = 0, _a = this.or; _i < _a.length; _i++) {
var tagsFilter = _a[_i];
if (tagsFilter.matches(tags)) {
return true;
}
}
return false;
};
Or.prototype.asOverpass = function () {
var choices = [];
for (var _i = 0, _a = this.or; _i < _a.length; _i++) {
var tagsFilter = _a[_i];
var subChoices = tagsFilter.asOverpass();
for (var _b = 0, subChoices_1 = subChoices; _b < subChoices_1.length; _b++) {
var subChoice = subChoices_1[_b];
choices.push(subChoice);
}
}
return choices;
};
Or.prototype.substituteValues = function (tags) {
var newChoices = [];
for (var _i = 0, _a = this.or; _i < _a.length; _i++) {
var c = _a[_i];
newChoices.push(c.substituteValues(tags));
}
return new Or(newChoices);
};
return Or;
}(TagsFilter));
exports.Or = Or;
var And = /** @class */ (function (_super) {
__extends(And, _super);
function And(and) {
var _this = _super.call(this) || this;
_this.and = and;
return _this;
}
And.prototype.matches = function (tags) {
for (var _i = 0, _a = this.and; _i < _a.length; _i++) {
var tagsFilter = _a[_i];
if (!tagsFilter.matches(tags)) {
return false;
}
}
return true;
};
And.prototype.combine = function (filter, choices) {
var values = [];
for (var _i = 0, choices_1 = choices; _i < choices_1.length; _i++) {
var or = choices_1[_i];
values.push(filter + or);
}
return values;
};
And.prototype.asOverpass = function () {
var allChoices = null;
for (var _i = 0, _a = this.and; _i < _a.length; _i++) {
var andElement = _a[_i];
var andElementFilter = andElement.asOverpass();
if (allChoices === null) {
allChoices = andElementFilter;
continue;
}
var newChoices = [];
for (var _b = 0, allChoices_1 = allChoices; _b < allChoices_1.length; _b++) {
var choice = allChoices_1[_b];
newChoices.push(this.combine(choice, andElementFilter));
}
allChoices = newChoices;
}
return allChoices;
};
And.prototype.substituteValues = function (tags) {
var newChoices = [];
for (var _i = 0, _a = this.and; _i < _a.length; _i++) {
var c = _a[_i];
newChoices.push(c.substituteValues(tags));
}
return new And(newChoices);
};
return And;
}(TagsFilter));
exports.And = And;
var Not = /** @class */ (function (_super) {
__extends(Not, _super);
function Not(not) {
var _this = _super.call(this) || this;
_this.not = not;
return _this;
}
Not.prototype.asOverpass = function () {
throw "Not supported yet";
};
Not.prototype.matches = function (tags) {
return !this.not.matches(tags);
};
Not.prototype.substituteValues = function (tags) {
return new Not(this.not.substituteValues(tags));
};
return Not;
}(TagsFilter));
exports.Not = Not;
var TagUtils = /** @class */ (function () {
function TagUtils() {
}
TagUtils.proprtiesToKV = function (properties) {
var result = [];
for (var k in properties) {
result.push({ k: k, v: properties[k] });
}
return result;
};
TagUtils.ApplyTemplate = function (template, tags) {
for (var k in tags) {
while (template.indexOf("{" + k + "}") >= 0) {
template = template.replace("{" + k + "}", tags[k]);
}
}
return template;
};
return TagUtils;
}());
exports.TagUtils = TagUtils;

View file

@ -1,135 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LicenseInfo = exports.ImagesInCategory = exports.Wikidata = exports.Wikimedia = void 0;
var $ = require("jquery");
/**
* This module provides endpoints for wikipedia/wikimedia and others
*/
var Wikimedia = /** @class */ (function () {
function Wikimedia() {
}
Wikimedia.ImageNameToUrl = function (filename, width, height) {
if (width === void 0) { width = 500; }
if (height === void 0) { height = 200; }
filename = encodeURIComponent(filename);
return "https://commons.wikimedia.org/wiki/Special:FilePath/" + filename + "?width=" + width + "&height=" + height;
};
Wikimedia.LicenseData = function (filename, handle) {
if (filename in this.knownLicenses) {
return this.knownLicenses[filename];
}
if (filename === "") {
return;
}
var url = "https://en.wikipedia.org/w/" +
"api.php?action=query&prop=imageinfo&iiprop=extmetadata&" +
"titles=" + filename +
"&format=json&origin=*";
$.getJSON(url, function (data, status) {
var _a, _b, _c, _d, _e, _f, _g, _h;
var licenseInfo = new LicenseInfo();
var license = data.query.pages[-1].imageinfo[0].extmetadata;
licenseInfo.artist = (_a = license.Artist) === null || _a === void 0 ? void 0 : _a.value;
licenseInfo.license = (_b = license.License) === null || _b === void 0 ? void 0 : _b.value;
licenseInfo.copyrighted = (_c = license.Copyrighted) === null || _c === void 0 ? void 0 : _c.value;
licenseInfo.attributionRequired = (_d = license.AttributionRequired) === null || _d === void 0 ? void 0 : _d.value;
licenseInfo.usageTerms = (_e = license.UsageTerms) === null || _e === void 0 ? void 0 : _e.value;
licenseInfo.licenseShortName = (_f = license.LicenseShortName) === null || _f === void 0 ? void 0 : _f.value;
licenseInfo.credit = (_g = license.Credit) === null || _g === void 0 ? void 0 : _g.value;
licenseInfo.description = (_h = license.ImageDescription) === null || _h === void 0 ? void 0 : _h.value;
Wikimedia.knownLicenses[filename] = licenseInfo;
handle(licenseInfo);
});
};
Wikimedia.GetCategoryFiles = function (categoryName, handleCategory, alreadyLoaded, continueParameter) {
var _this = this;
if (alreadyLoaded === void 0) { alreadyLoaded = 0; }
if (continueParameter === void 0) { continueParameter = undefined; }
if (categoryName === undefined || categoryName === null || categoryName === "") {
return;
}
// @ts-ignore
if (!categoryName.startsWith("Category:")) {
categoryName = "Category:" + categoryName;
}
var url = "https://commons.wikimedia.org/w/api.php?" +
"action=query&list=categorymembers&format=json&" +
"&origin=*" +
"&cmtitle=" + encodeURIComponent(categoryName);
if (continueParameter !== undefined) {
url = url + "&" + continueParameter.k + "=" + continueParameter.param;
}
$.getJSON(url, function (response) {
var _a;
var imageOverview = new ImagesInCategory();
var members = (_a = response.query) === null || _a === void 0 ? void 0 : _a.categorymembers;
if (members === undefined) {
members = [];
}
for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
var member = members_1[_i];
imageOverview.images.push(member.title);
}
if (response.continue === undefined || alreadyLoaded > 30) {
handleCategory(imageOverview);
}
else {
console.log("Recursive load for ", categoryName);
_this.GetCategoryFiles(categoryName, function (recursiveImages) {
for (var _i = 0, _a = imageOverview.images; _i < _a.length; _i++) {
var image = _a[_i];
recursiveImages.images.push(image);
}
handleCategory(recursiveImages);
}, alreadyLoaded + 10, { k: "cmcontinue", param: response.continue.cmcontinue });
}
});
};
Wikimedia.GetWikiData = function (id, handleWikidata) {
var url = "https://www.wikidata.org/wiki/Special:EntityData/Q" + id + ".json";
$.getJSON(url, function (response) {
var _a, _b, _c, _d;
var entity = response.entities["Q" + id];
var commons = entity.sitelinks.commonswiki;
var wd = new Wikidata();
wd.commonsWiki = commons === null || commons === void 0 ? void 0 : commons.title;
// P18 is the claim 'depicted in this image'
var image = (_d = (_c = (_b = (_a = entity.claims.P18) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.mainsnak) === null || _c === void 0 ? void 0 : _c.datavalue) === null || _d === void 0 ? void 0 : _d.value;
if (image) {
wd.image = "File:" + image;
}
handleWikidata(wd);
});
};
Wikimedia.knownLicenses = {};
return Wikimedia;
}());
exports.Wikimedia = Wikimedia;
var Wikidata = /** @class */ (function () {
function Wikidata() {
}
return Wikidata;
}());
exports.Wikidata = Wikidata;
var ImagesInCategory = /** @class */ (function () {
function ImagesInCategory() {
// Filenames of relevant images
this.images = [];
}
return ImagesInCategory;
}());
exports.ImagesInCategory = ImagesInCategory;
var LicenseInfo = /** @class */ (function () {
function LicenseInfo() {
this.artist = "";
this.license = "";
this.licenseShortName = "";
this.usageTerms = "";
this.attributionRequired = false;
this.copyrighted = false;
this.credit = "";
this.description = "";
}
return LicenseInfo;
}());
exports.LicenseInfo = LicenseInfo;