forked from MapComplete/MapComplete
Add binoculars theme, auto reformat everything
This commit is contained in:
parent
38dea806c5
commit
78d6482c88
586 changed files with 115573 additions and 111842 deletions
|
@ -8,11 +8,10 @@ import {GeoOperations} from "../../GeoOperations";
|
|||
|
||||
export default class CreateNewNodeAction extends OsmChangeAction {
|
||||
|
||||
public newElementId: string = undefined
|
||||
private readonly _basicTags: Tag[];
|
||||
private readonly _lat: number;
|
||||
private readonly _lon: number;
|
||||
|
||||
public newElementId: string = undefined
|
||||
private readonly _snapOnto: OsmWay;
|
||||
private readonly _reusePointDistance: number;
|
||||
|
||||
|
@ -21,7 +20,7 @@ export default class CreateNewNodeAction extends OsmChangeAction {
|
|||
this._basicTags = basicTags;
|
||||
this._lat = lat;
|
||||
this._lon = lon;
|
||||
if(lat === undefined || lon === undefined){
|
||||
if (lat === undefined || lon === undefined) {
|
||||
throw "Lat or lon are undefined!"
|
||||
}
|
||||
this._snapOnto = options?.snapOnto;
|
||||
|
@ -82,20 +81,20 @@ export default class CreateNewNodeAction extends OsmChangeAction {
|
|||
id: reusedPointId
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
const locations = [...this._snapOnto.coordinates]
|
||||
locations.forEach(coor => coor.reverse())
|
||||
console.log("Locations are: ", locations)
|
||||
const ids = [...this._snapOnto.nodes]
|
||||
|
||||
|
||||
locations.splice(index + 1, 0, [this._lon, this._lat])
|
||||
ids.splice(index + 1, 0, id)
|
||||
|
||||
|
||||
// Allright, we have to insert a new point in the way
|
||||
return [
|
||||
newPointChange,
|
||||
{
|
||||
type:"way",
|
||||
type: "way",
|
||||
id: this._snapOnto.id,
|
||||
changes: {
|
||||
locations: locations,
|
||||
|
|
|
@ -30,7 +30,7 @@ export default class DeleteAction {
|
|||
* Does actually delete the feature; returns the event source 'this.isDeleted'
|
||||
* If deletion is not allowed, triggers the callback instead
|
||||
*/
|
||||
public DoDelete(reason: string, onNotAllowed : () => void): void {
|
||||
public DoDelete(reason: string, onNotAllowed: () => void): void {
|
||||
const isDeleted = this.isDeleted
|
||||
const self = this;
|
||||
let deletionStarted = false;
|
||||
|
@ -40,23 +40,21 @@ export default class DeleteAction {
|
|||
// Already deleted...
|
||||
return;
|
||||
}
|
||||
|
||||
if(canBeDeleted.canBeDeleted === false){
|
||||
|
||||
if (canBeDeleted.canBeDeleted === false) {
|
||||
// We aren't allowed to delete
|
||||
deletionStarted = true;
|
||||
onNotAllowed();
|
||||
isDeleted.setData(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!canBeDeleted) {
|
||||
// We are not allowed to delete (yet), this might change in the future though
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
deletionStarted = true;
|
||||
OsmObject.DownloadObject(self._id).addCallbackAndRun(obj => {
|
||||
if (obj === undefined) {
|
||||
|
@ -207,7 +205,7 @@ export default class DeleteAction {
|
|||
canBeDeleted: false,
|
||||
reason: t.partOfOthers
|
||||
})
|
||||
}else{
|
||||
} else {
|
||||
// alright, this point can be safely deleted!
|
||||
state.setData({
|
||||
canBeDeleted: true,
|
||||
|
@ -215,7 +213,6 @@ export default class DeleteAction {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/**
|
||||
* The logic to handle relations after a way within
|
||||
* The logic to handle relations after a way within
|
||||
*/
|
||||
import OsmChangeAction from "./OsmChangeAction";
|
||||
import {Changes} from "../Changes";
|
||||
import {ChangeDescription} from "./ChangeDescription";
|
||||
import {OsmRelation, OsmWay} from "../OsmObject";
|
||||
import {OsmRelation} from "../OsmObject";
|
||||
|
||||
export default class RelationSplitlHandler extends OsmChangeAction{
|
||||
export default class RelationSplitlHandler extends OsmChangeAction {
|
||||
|
||||
constructor(partOf: OsmRelation[], newWayIds: number[], originalNodes: number[]) {
|
||||
super()
|
||||
|
|
|
@ -23,18 +23,18 @@ export class Changes {
|
|||
|
||||
public readonly pendingChanges = LocalStorageSource.GetParsed<ChangeDescription[]>("pending-changes", [])
|
||||
private readonly isUploading = new UIEventSource(false);
|
||||
|
||||
private readonly previouslyCreated : OsmObject[] = []
|
||||
|
||||
private readonly previouslyCreated: OsmObject[] = []
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
private static createChangesetFor(csId: string,
|
||||
allChanges: {
|
||||
modifiedObjects: OsmObject[],
|
||||
newObjects: OsmObject[],
|
||||
deletedObjects: OsmObject[]
|
||||
}): string {
|
||||
allChanges: {
|
||||
modifiedObjects: OsmObject[],
|
||||
newObjects: OsmObject[],
|
||||
deletedObjects: OsmObject[]
|
||||
}): string {
|
||||
|
||||
const changedElements = allChanges.modifiedObjects ?? []
|
||||
const newElements = allChanges.newObjects ?? []
|
||||
|
@ -70,6 +70,88 @@ export class Changes {
|
|||
.map(c => c.type + "/" + c.id))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ID and updates the value for the next ID
|
||||
*/
|
||||
public getNewID() {
|
||||
return Changes._nextId--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads all the pending changes in one go.
|
||||
* Triggered by the 'PendingChangeUploader'-actor in Actors
|
||||
*/
|
||||
public flushChanges(flushreason: string = undefined) {
|
||||
if (this.pendingChanges.data.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isUploading.data) {
|
||||
console.log("Is already uploading... Abort")
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.isUploading.setData(true)
|
||||
|
||||
console.log("Beginning upload... " + flushreason ?? "");
|
||||
// At last, we build the changeset and upload
|
||||
const self = this;
|
||||
const pending = self.pendingChanges.data;
|
||||
const neededIds = Changes.GetNeededIds(pending)
|
||||
console.log("Needed ids", neededIds)
|
||||
OsmObject.DownloadAll(neededIds, true).addCallbackAndRunD(osmObjects => {
|
||||
console.log("Got the fresh objects!", osmObjects, "pending: ", pending)
|
||||
try {
|
||||
|
||||
|
||||
const changes: {
|
||||
newObjects: OsmObject[],
|
||||
modifiedObjects: OsmObject[]
|
||||
deletedObjects: OsmObject[]
|
||||
|
||||
} = self.CreateChangesetObjects(pending, osmObjects)
|
||||
if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) {
|
||||
console.log("No changes to be made")
|
||||
self.pendingChanges.setData([])
|
||||
self.isUploading.setData(false)
|
||||
return true; // Unregister the callback
|
||||
}
|
||||
|
||||
|
||||
State.state.osmConnection.UploadChangeset(
|
||||
State.state.layoutToUse.data,
|
||||
State.state.allElements,
|
||||
(csId) => Changes.createChangesetFor(csId, changes),
|
||||
() => {
|
||||
console.log("Upload successfull!")
|
||||
self.pendingChanges.setData([]);
|
||||
self.isUploading.setData(false)
|
||||
},
|
||||
() => {
|
||||
console.log("Upload failed - trying again later")
|
||||
return self.isUploading.setData(false);
|
||||
} // Failed - mark to try again
|
||||
)
|
||||
} catch (e) {
|
||||
console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e)
|
||||
self.pendingChanges.setData([])
|
||||
self.isUploading.setData(false)
|
||||
}
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
public applyAction(action: OsmChangeAction) {
|
||||
const changes = action.Perform(this)
|
||||
console.log("Received changes:", changes)
|
||||
this.pendingChanges.data.push(...changes);
|
||||
this.pendingChanges.ping();
|
||||
}
|
||||
|
||||
private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
||||
newObjects: OsmObject[],
|
||||
modifiedObjects: OsmObject[]
|
||||
|
@ -85,7 +167,7 @@ export class Changes {
|
|||
}
|
||||
|
||||
for (const o of this.previouslyCreated) {
|
||||
objects.set(o.type + "/" + o.id, o)
|
||||
objects.set(o.type + "/" + o.id, o)
|
||||
states.set(o.type + "/" + o.id, "unchanged")
|
||||
}
|
||||
|
||||
|
@ -93,8 +175,8 @@ export class Changes {
|
|||
for (const change of changes) {
|
||||
const id = change.type + "/" + change.id
|
||||
if (!objects.has(id)) {
|
||||
if(change.id >= 0){
|
||||
throw "Did not get an object that should be known: "+id
|
||||
if (change.id >= 0) {
|
||||
throw "Did not get an object that should be known: " + id
|
||||
}
|
||||
// This is a new object that should be created
|
||||
states.set(id, "created")
|
||||
|
@ -189,7 +271,7 @@ export class Changes {
|
|||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (changed && state === "unchanged") {
|
||||
|
@ -203,7 +285,7 @@ export class Changes {
|
|||
modifiedObjects: [],
|
||||
deletedObjects: []
|
||||
}
|
||||
|
||||
|
||||
objects.forEach((v, id) => {
|
||||
|
||||
const state = states.get(id)
|
||||
|
@ -221,86 +303,4 @@ export class Changes {
|
|||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ID and updates the value for the next ID
|
||||
*/
|
||||
public getNewID() {
|
||||
return Changes._nextId--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads all the pending changes in one go.
|
||||
* Triggered by the 'PendingChangeUploader'-actor in Actors
|
||||
*/
|
||||
public flushChanges(flushreason: string = undefined) {
|
||||
if (this.pendingChanges.data.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isUploading.data) {
|
||||
console.log("Is already uploading... Abort")
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.isUploading.setData(true)
|
||||
|
||||
console.log("Beginning upload... "+flushreason ?? "");
|
||||
// At last, we build the changeset and upload
|
||||
const self = this;
|
||||
const pending = self.pendingChanges.data;
|
||||
const neededIds = Changes.GetNeededIds(pending)
|
||||
console.log("Needed ids", neededIds)
|
||||
OsmObject.DownloadAll(neededIds, true).addCallbackAndRunD(osmObjects => {
|
||||
console.log("Got the fresh objects!", osmObjects, "pending: ", pending)
|
||||
try{
|
||||
|
||||
|
||||
const changes: {
|
||||
newObjects: OsmObject[],
|
||||
modifiedObjects: OsmObject[]
|
||||
deletedObjects: OsmObject[]
|
||||
|
||||
} = self.CreateChangesetObjects(pending, osmObjects)
|
||||
if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) {
|
||||
console.log("No changes to be made")
|
||||
self.pendingChanges.setData([])
|
||||
self.isUploading.setData(false)
|
||||
return true; // Unregister the callback
|
||||
}
|
||||
|
||||
|
||||
State.state.osmConnection.UploadChangeset(
|
||||
State.state.layoutToUse.data,
|
||||
State.state.allElements,
|
||||
(csId) => Changes.createChangesetFor(csId, changes),
|
||||
() => {
|
||||
console.log("Upload successfull!")
|
||||
self.pendingChanges.setData([]);
|
||||
self.isUploading.setData(false)
|
||||
},
|
||||
() => {
|
||||
console.log("Upload failed - trying again later")
|
||||
return self.isUploading.setData(false);
|
||||
} // Failed - mark to try again
|
||||
)
|
||||
}catch(e){
|
||||
console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e)
|
||||
self.pendingChanges.setData([])
|
||||
self.isUploading.setData(false)
|
||||
}
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
public applyAction(action: OsmChangeAction) {
|
||||
const changes = action.Perform(this)
|
||||
console.log("Received changes:", changes)
|
||||
this.pendingChanges.data.push(...changes);
|
||||
this.pendingChanges.ping();
|
||||
}
|
||||
}
|
|
@ -258,7 +258,7 @@ export class ChangesetHandler {
|
|||
}, function (err, response) {
|
||||
if (response === undefined) {
|
||||
console.log("err", err);
|
||||
if(options.onFail){
|
||||
if (options.onFail) {
|
||||
options.onFail()
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -15,7 +15,7 @@ export interface Relation {
|
|||
|
||||
export default class ExtractRelations {
|
||||
|
||||
public static RegisterRelations(overpassJson: any) : void{
|
||||
public static RegisterRelations(overpassJson: any): void {
|
||||
const memberships = ExtractRelations.BuildMembershipTable(ExtractRelations.GetRelationElements(overpassJson))
|
||||
State.state.knownRelations.setData(memberships)
|
||||
}
|
||||
|
|
|
@ -6,12 +6,14 @@ export class Geocoding {
|
|||
private static readonly host = "https://nominatim.openstreetmap.org/search?";
|
||||
|
||||
static Search(query: string,
|
||||
handleResult: ((places: { display_name: string, lat: number, lon: number, boundingbox: number[],
|
||||
osm_type: string, osm_id: string}[]) => void),
|
||||
handleResult: ((places: {
|
||||
display_name: string, lat: number, lon: number, boundingbox: number[],
|
||||
osm_type: string, osm_id: string
|
||||
}[]) => void),
|
||||
onFail: (() => void)) {
|
||||
const b = State.state.leafletMap.data.getBounds();
|
||||
const url = Geocoding.host + "format=json&limit=1&viewbox=" +
|
||||
`${b.getEast()},${b.getNorth()},${b.getWest()},${b.getSouth()}`+
|
||||
`${b.getEast()},${b.getNorth()},${b.getWest()},${b.getSouth()}` +
|
||||
"&accept-language=nl&q=" + query;
|
||||
Utils.downloadJson(
|
||||
url)
|
||||
|
|
|
@ -22,7 +22,7 @@ export default class UserDetails {
|
|||
public dryRun: boolean;
|
||||
home: { lon: number; lat: number };
|
||||
public backend: string;
|
||||
|
||||
|
||||
constructor(backend: string) {
|
||||
this.backend = backend;
|
||||
}
|
||||
|
@ -47,10 +47,10 @@ export class OsmConnection {
|
|||
public auth;
|
||||
public userDetails: UIEventSource<UserDetails>;
|
||||
public isLoggedIn: UIEventSource<boolean>
|
||||
private fakeUser: boolean;
|
||||
_dryRun: boolean;
|
||||
public preferencesHandler: OsmPreferences;
|
||||
public changesetHandler: ChangesetHandler;
|
||||
private fakeUser: boolean;
|
||||
private _onLoggedIn: ((userDetails: UserDetails) => void)[] = [];
|
||||
private readonly _iframeMode: Boolean | boolean;
|
||||
private readonly _singlePage: boolean;
|
||||
|
@ -59,8 +59,9 @@ export class OsmConnection {
|
|||
oauth_secret: string,
|
||||
url: string
|
||||
};
|
||||
private isChecking = false;
|
||||
|
||||
constructor(dryRun: boolean,
|
||||
constructor(dryRun: boolean,
|
||||
fakeUser: boolean,
|
||||
oauth_token: UIEventSource<string>,
|
||||
// Used to keep multiple changesets open and to write to the correct changeset
|
||||
|
@ -77,17 +78,17 @@ export class OsmConnection {
|
|||
|
||||
this.userDetails = new UIEventSource<UserDetails>(new UserDetails(this._oauth_config.url), "userDetails");
|
||||
this.userDetails.data.dryRun = dryRun || fakeUser;
|
||||
if(fakeUser){
|
||||
if (fakeUser) {
|
||||
const ud = this.userDetails.data;
|
||||
ud.csCount = 5678
|
||||
ud.loggedIn= true;
|
||||
ud.loggedIn = true;
|
||||
ud.unreadMessages = 0
|
||||
ud.name = "Fake user"
|
||||
ud.totalMessages = 42;
|
||||
}
|
||||
const self =this;
|
||||
const self = this;
|
||||
this.isLoggedIn = this.userDetails.map(user => user.loggedIn).addCallback(isLoggedIn => {
|
||||
if(self.userDetails.data.loggedIn == false && isLoggedIn == true){
|
||||
if (self.userDetails.data.loggedIn == false && isLoggedIn == true) {
|
||||
// We have an inconsistency: the userdetails say we _didn't_ log in, but this actor says we do
|
||||
// This means someone attempted to toggle this; so we attempt to login!
|
||||
self.AttemptLogin()
|
||||
|
@ -150,7 +151,7 @@ export class OsmConnection {
|
|||
}
|
||||
|
||||
public AttemptLogin() {
|
||||
if(this.fakeUser){
|
||||
if (this.fakeUser) {
|
||||
console.log("AttemptLogin called, but ignored as fakeUser is set")
|
||||
return;
|
||||
}
|
||||
|
@ -191,7 +192,7 @@ export class OsmConnection {
|
|||
data.loggedIn = true;
|
||||
console.log("Login completed, userinfo is ", userInfo);
|
||||
data.name = userInfo.getAttribute('display_name');
|
||||
data.uid= Number(userInfo.getAttribute("id"))
|
||||
data.uid = Number(userInfo.getAttribute("id"))
|
||||
data.csCount = userInfo.getElementsByTagName("changesets")[0].getAttribute("count");
|
||||
|
||||
data.img = undefined;
|
||||
|
@ -249,20 +250,19 @@ export class OsmConnection {
|
|||
});
|
||||
}
|
||||
|
||||
private isChecking = false;
|
||||
private CheckForMessagesContinuously(){
|
||||
const self =this;
|
||||
if(this.isChecking){
|
||||
private CheckForMessagesContinuously() {
|
||||
const self = this;
|
||||
if (this.isChecking) {
|
||||
return;
|
||||
}
|
||||
this.isChecking = true;
|
||||
UIEventSource.Chronic(5 * 60 * 1000).addCallback(_ => {
|
||||
if (self.isLoggedIn .data) {
|
||||
console.log("Checking for messages")
|
||||
self.AttemptLogin();
|
||||
}
|
||||
if (self.isLoggedIn.data) {
|
||||
console.log("Checking for messages")
|
||||
self.AttemptLogin();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ export abstract class OsmObject {
|
|||
const splitted = id.split("/");
|
||||
const type = splitted[0];
|
||||
const idN = Number(splitted[1]);
|
||||
if(idN <0){
|
||||
if (idN < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -438,7 +438,7 @@ export class OsmWay extends OsmObject {
|
|||
|
||||
for (const nodeId of element.nodes) {
|
||||
const node = nodeDict.get(nodeId)
|
||||
if(node === undefined){
|
||||
if (node === undefined) {
|
||||
console.error("Error: node ", nodeId, "not found in ", nodeDict)
|
||||
// This is probably part of a relation which hasn't been fully downloaded
|
||||
continue;
|
||||
|
@ -498,7 +498,7 @@ export class OsmRelation extends OsmObject {
|
|||
|
||||
let tags = this.TagsXML();
|
||||
let cs = ""
|
||||
if(changesetId !== undefined){
|
||||
if (changesetId !== undefined) {
|
||||
cs = `changeset="${changesetId}"`
|
||||
}
|
||||
return ` <relation id="${this.id}" ${cs} ${this.VersionXML()}>
|
||||
|
|
|
@ -29,7 +29,7 @@ export class OsmPreferences {
|
|||
return this.longPreferences[prefix + key];
|
||||
}
|
||||
|
||||
const source = new UIEventSource<string>(undefined, "long-osm-preference:"+prefix+key);
|
||||
const source = new UIEventSource<string>(undefined, "long-osm-preference:" + prefix + key);
|
||||
this.longPreferences[prefix + key] = source;
|
||||
|
||||
const allStartWith = prefix + key + "-combined";
|
||||
|
@ -107,7 +107,7 @@ export class OsmPreferences {
|
|||
if (this.userDetails.data.loggedIn && this.preferences.data[key] === undefined) {
|
||||
this.UpdatePreferences();
|
||||
}
|
||||
const pref = new UIEventSource<string>(this.preferences.data[key],"osm-preference:"+key);
|
||||
const pref = new UIEventSource<string>(this.preferences.data[key], "osm-preference:" + key);
|
||||
pref.addCallback((v) => {
|
||||
this.SetPreference(key, v);
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ export class Overpass {
|
|||
private readonly _timeout: UIEventSource<number>;
|
||||
private readonly _extraScripts: string[];
|
||||
private _includeMeta: boolean;
|
||||
|
||||
|
||||
constructor(filter: TagsFilter, extraScripts: string[],
|
||||
interpreterUrl: UIEventSource<string>,
|
||||
timeout: UIEventSource<number>,
|
||||
|
@ -42,7 +42,7 @@ export class Overpass {
|
|||
onFail("Runtime error (timeout)")
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ExtractRelations.RegisterRelations(json)
|
||||
// @ts-ignore
|
||||
|
|
|
@ -12,12 +12,9 @@ export default class AspectedRouting {
|
|||
this.program = JSON.parse(JSON.stringify(program))
|
||||
delete this.program.name
|
||||
delete this.program.description
|
||||
delete this.program.unit
|
||||
delete this.program.unit
|
||||
}
|
||||
|
||||
public evaluate(properties){
|
||||
return AspectedRouting.interpret(this.program, properties)
|
||||
}
|
||||
/**
|
||||
* Interprets the given Aspected-routing program for the given properties
|
||||
*/
|
||||
|
@ -191,4 +188,8 @@ export default class AspectedRouting {
|
|||
return result;
|
||||
}
|
||||
|
||||
public evaluate(properties) {
|
||||
return AspectedRouting.interpret(this.program, properties)
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue