// ==UserScript==
// @name WME Add addresses for places
// @version 0.20.1
// @description Добавление альтернативных названий (адресов)
// @author ixxvivxxi, Vinkoy
// @include https://www.waze.com/editor/*
// @include https://www.waze.com/*/editor/*
// @include https://editor-beta.waze.com/editor/*
// @include https://editor-beta.waze.com/*/editor/*
// @grant none
// @namespace https://greasyfork.org/ru/scripts/12229-wme-add-alt-address-for-housing
// ==/UserScript==
function altAddress_bootstrap()
{
var bGreasemonkeyServiceDefined = false;
try
{
if("object" === typeof Components.interfaces.gmIGreasemonkeyService)
{
bGreasemonkeyServiceDefined = true;
}
}
catch(err)
{
//Ignore.
}
if("undefined" === typeof unsafeWindow || !bGreasemonkeyServiceDefined)
{
unsafeWindow = (function()
{
var dummyElem = document.createElement('p');
dummyElem.setAttribute('onclick', 'return window;');
return dummyElem.onclick();
})();
}
/* begin running the code! */
setTimeout(startAltAddress, 999);
}
function startAltAddress()
{
var POIaddresses = [];
var POIs = [];
Waze.selectionManager.events.register("selectionchanged", null, showTitle);
$('#sidebar').on('click', '#addPOIs', function(event) {
event.preventDefault();
addPOIs();
});
Waze.model.events.register('mergeend', null, getPOIs);
Waze.model.events.register('zoomend', null, getPOIs);
Waze.model.events.register('moveend', null, getPOIs);
var wazeActionAddLandmark = require("Waze/Action/AddLandmark");
var wazeActionUpdateObject = require("Waze/Action/UpdateObject");
var wazeActionDeleteObject = require("Waze/Action/DeleteObject");
var wazeActionUpdateFeatureAddress = require("Waze/Action/UpdateFeatureAddress");
var wazefeatureVectorLandmark = require("Waze/Feature/Vector/Landmark");
var address;
var selectStreetName = "";
addTab();
localDataManager();
function addTab()
{
if(!document.getElementById(CreateID()))
{
var btnSection = document.createElement('div');
btnSection.id = CreateID();
var userTabs = document.getElementById('user-info');
if (!(userTabs && getElementsByClassName('nav-tabs', userTabs)))
return;
var navTabs = getElementsByClassName('nav-tabs', userTabs)[0];
if (typeof navTabs !== "undefined")
{
if (!getElementsByClassName('tab-content', userTabs))
return;
var tabContent = getElementsByClassName('tab-content', userTabs)[0];
if (typeof tabContent !== "undefined")
{
newtab = document.createElement('li');
newtab.innerHTML = '<a href="#' + CreateID() + '" data-toggle="tab"><span class="fa fa-home"></span></a>';
navTabs.appendChild(newtab);
btnSection.innerHTML = '<div class="form-group">'+
'<h4><span class="fa fa-home"> Add addresses for places <sup>' + GM_info.script.version + '</sup> </h4>' +
'</br>' +
'<div title="Создавать ПТ"><input type="checkbox" id="_createRH" /><b> Создавать ПТ</b></div>' +
'<div title="Создавать POI-точки"><input type="checkbox" id="_createPOI" /><b> Создавать POI-точки</b></div>' +
'<div title="Обновлять контуры"><input type="checkbox" id="_updatePlaces" /><b> Обновлять контуры</b></div>' +
'<div title="Обновлять блокировку"><input type="checkbox" id="_updateLock" /><b> Обновлять блокировку</b></div>' +
'<div title="Выравнивать POI и ПТ по ХН"><input type="checkbox" id="_allignToHN" /><b> Выравнивать по ХН</b></div>' +
'<div title="Уровень блокировки"><b>Уровень блокировки </b>' +
'<select id="_lockLevel" style="padding-left: 30px;margin-left: 10px;" ><option value="0">1</option><option value="1">2</option><option value="2">3</option><option value="3">4</option><option value="4">5</option></select></div>' +
'</div>';
btnSection.className = "tab-pane";
tabContent.appendChild(btnSection);
}
else
btnSection.id='';
}
else
btnSection.id='';
}
}
function CreateID()
{
return 'WME-addAddress';
}
function localDataManager()
{
// restore saved settings
if (localStorage.WMEaddAddress)
{
options = JSON.parse(localStorage.WMEaddAddress);
if(options[1] !== undefined)
document.getElementById('_lockLevel').selectedIndex = options[1];
else
document.getElementById('_lockLevel').selectedIndex = 0;
document.getElementById('_createRH').checked = options[2];
document.getElementById('_createPOI').checked = options[3];
document.getElementById('_updatePlaces').checked = options[4];
document.getElementById('_updateLock').checked = options[5];
document.getElementById('_allignToHN').checked = options[6];
}
else
{
document.getElementById('_lockLevel').selectedIndex = 0;
document.getElementById('_createRH').checked = true;
document.getElementById('_createPOI').checked = true;
document.getElementById('_updatePlaces').checked = true;
document.getElementById('_updateLock').checked = true;
document.getElementById('_allignToHN').checked = true;
}
// overload the WME exit function
wme_saveaddAddressOptions = function()
{
if (localStorage)
{
var options = [];
// preserve previous options which may get lost after logout
if (localStorage.WMEaddAddress)
options = JSON.parse(localStorage.WMEaddAddress);
options[1] = document.getElementById('_lockLevel').selectedIndex;
options[2] = document.getElementById('_createRH').checked;
options[3] = document.getElementById('_createPOI').checked;
options[4] = document.getElementById('_updatePlaces').checked;
options[5] = document.getElementById('_updateLock').checked;
options[6] = document.getElementById('_allignToHN').checked;
localStorage.WMEaddAddress = JSON.stringify(options);
}
};
window.addEventListener("beforeunload", wme_saveaddAddressOptions, false);
}
function getPOIs()
{
for(var idVenue in Waze.model.venues.objects)
{
var venue = Waze.model.venues.objects[idVenue];
var venueAddressDetails = venue.getAddress();
if(selectStreetName === null || venueAddressDetails === null || venueAddressDetails.
attributes.isEmpty === true) {continue;}
if(venueAddressDetails.attributes.street.name == selectStreetName && selectStreetName !== "")
{
$("g[id^='Waze.Layer.FeatureLayer']").find("svg[id='" + venue.geometry.id + "']").attr('stroke', 'yellow');
$("g[id^='Waze.Layer.FeatureLayer']").find("circle[id='" + venue.geometry.id + "']").attr('stroke', 'yellow');
$("g[id^='Waze.Layer.FeatureLayer']").find("path[id='" + venue.geometry.id + "']").attr('stroke', 'yellow');
}
var inPois = false;
var category = venue.getMainCategory();
if(category == "NATURAL_FEATURES" || category == "OUTDOORS")
{
inPois = true;
}
for(var ir = 0; ir < POIs.length; ir++)
{
if(POIs[ir].attributes.id.toString().indexOf("-") != -1) {continue;}
if(POIs[ir].attributes.id === idVenue)
{
POIs[ir] = venue;
inPois = true;
}
}
if(!inPois)
{
POIs.push(venue);
}
}
}
function addClass()
{
if(POIs.length === 0) getPOIs();
$("g[id^='Waze.Layer.FeatureLayer']").find("svg[id^='OpenLayers.Geometry.Point']").attr('stroke', 'white');
$("g[id^='Waze.Layer.FeatureLayer']").find("circle[id^='OpenLayers.Geometry.Point']").attr('stroke', 'white');
$("g[id^='Waze.Layer.FeatureLayer']").find("path[id^='OpenLayers.Geometry.Polygon']").attr('stroke', '#ca9ace');
for(var ir = 0; ir < POIs.length; ir++)
{
var venueAddressDetails = POIs[ir].getAddress();
if(selectStreetName === null || selectStreetName === "" || venueAddressDetails === null || venueAddressDetails.attributes.isEmpty === true){continue;}
if(venueAddressDetails.attributes.street.name == selectStreetName)
{
$("g[id^='Waze.Layer.FeatureLayer']").find("svg[id='" + POIs[ir].geometry.id + "']").attr('stroke', 'yellow');
$("g[id^='Waze.Layer.FeatureLayer']").find("circle[id='" + POIs[ir].geometry.id + "']").attr('stroke', 'yellow');
$("g[id^='Waze.Layer.FeatureLayer']").find("path[id='" + POIs[ir].geometry.id + "']").attr('stroke', 'yellow');
}
}
}
function showTitle()
{
if(Waze.selectionManager.selectedItems.length === 0 || Waze.selectionManager.selectedItems.length > 1)
{
$("g[id^='Waze.Layer.FeatureLayer']").find("svg[id^='OpenLayers.Geometry.Point']").attr('stroke', 'white');
$("g[id^='Waze.Layer.FeatureLayer']").find("circle[id^='OpenLayers.Geometry.Point']").attr('stroke', 'white');
$("g[id^='Waze.Layer.FeatureLayer']").find("path[id^='OpenLayers.Geometry.Polygon']").attr('stroke', '#ca9ace');
return;
}
if(Waze.selectionManager.selectedItems[0].model.type == "segment")
{
if(Waze.selectionManager.selectedItems[0].model.attributes.id.toString().indexOf("-") == -1)
{
address = Waze.selectionManager.selectedItems[0].model.getAddress();
//console.log(address);
var title = "Update addresses";
if(address.country.id == 37 || address.country.id == 186)
{
title = "Обновить адреса";
}
selectStreetName = address.street.name;
if(selectStreetName !== null)
$('.more-actions').append('<button id="addPOIs" class="action-button btn btn-default">' + title + '</button>');
addClass();
}
}
}
function createPOI(poiobject, isRH)
{
var poi = new wazefeatureVectorLandmark();
var geometry = new OpenLayers.Geometry.Point();
geometry.x = poiobject.x - 1 + (isRH ? 2 : 0);
geometry.y = poiobject.y;
poi.geometry = geometry;
poi.attributes.categories = ["OTHER"];
poi.attributes.name = poiobject.houseNumber;
poi.attributes.lockRank = document.getElementById('_lockLevel').selectedIndex;
if(hasChar(poiobject.houseNumber) || poiobject.houseNumber.indexOf("/") !== -1)
{
poi.attributes.aliases.push(poiobject.houseNumber + " " + poiobject.streetName);
poi.attributes.name = poiobject.houseNumber;
}
if(poiobject.houseNumber.indexOf("/") != -1)
{
poi.attributes.aliases.push(poiobject.houseNumber.replace('/', 'к') + " " + poiobject.streetName);
poi.attributes.aliases.push(poiobject.houseNumber.replace('/', ' корпус ') + " " + poiobject.streetName);
}
if(isRH && (hasChar(poiobject.houseNumber) || poiobject.houseNumber.indexOf("/") != -1))
{
return;
}
Waze.model.actionManager.add(new wazeActionAddLandmark(poi));
var poiAddress = poi.getAddress().attributes;
if(poiAddress.city === null) {return;}
var newAddressAtts = {
streetName: poiobject.streetName,
emptyStreet: false,
cityName: (poiAddress.city.attributes.name.indexOf(poiobject.cityName) != -1) ? poiAddress.city.attributes.name : poiobject.cityName,
emptyCity: false,
stateID: poiAddress.state.id,
countryID: poiAddress.country.id
};
Waze.model.actionManager.add(new wazeActionUpdateFeatureAddress(poi, newAddressAtts,{streetIDField: 'streetID'}));
Waze.model.actionManager.add(new wazeActionUpdateObject(poi,{houseNumber: poiobject.houseNumber,residential: isRH}));
POIs.push(poi);
}
function addPOIs()
{
getPOIs();
$(".more-actions .edit-house-numbers").click();
setTimeout(function()
{
$('#map-lightbox .cancel').click();
for(var key in Waze.model.houseNumbers.objects)
{
//if (key != address.street.id) {continue;}
if(Waze.model.houseNumbers.objects[key].numbers.length > 0)
{
for(var i = 0; i < Waze.model.houseNumbers.objects[key].numbers.length; i++)
{
console.log(Waze.model.houseNumbers.objects[key].getSegment());
if(Waze.model.houseNumbers.objects[key].getSegment() === undefined) {continue;}
if(Waze.model.houseNumbers.objects[key].getSegment().getAddress().street === null) {continue;}
if(Waze.model.houseNumbers.objects[key].getSegment().getAddress().street.name != address.street.name) {continue;}
if(!Waze.map.getExtent().intersectsBounds(Waze.model.houseNumbers.objects[key].numbers[i].geometry.getBounds())) {continue;}
var number = Waze.model.houseNumbers.objects[key].numbers[i].number;
var hasPOI = false;
var hasRH = false;
for(var ir = 0; ir < POIs.length; ir++)
{
var venue = POIs[ir];
var venueAddress = venue.getAddress().attributes;
if(venueAddress === null || venueAddress.isEmpty === true) {continue;}
if(address.city.attributes.name.indexOf(venueAddress.city.attributes.name) != -1 && address.street.name == venueAddress.street.name && number == venueAddress.houseNumber)
{
if (document.getElementById('_updateLock').checked && venue.attributes.lockRank < document.getElementById('_lockLevel').selectedIndex)
{
var newLock = {};
newLock.lockRank = document.getElementById('_lockLevel').selectedIndex;
Waze.model.actionManager.add(new wazeActionUpdateObject(venue, newLock));
}
if(venue.isResidential())
hasRH = true;
else
hasPOI = true;
if(venue.isPoint() && document.getElementById('_allignToHN').checked)
{
if(venue.isResidential())
{
var oldCoord = venue.geometry.clone();
var newCoord = Waze.model.houseNumbers.objects[key].numbers[i].geometry.clone();
if ((oldCoord.x.toFixed(1) !== (newCoord.x+1).toFixed(1)) || (oldCoord.y.toFixed(1) !== newCoord.y.toFixed(1)))
{
newCoord.x++;
Waze.model.actionManager.add(new WazeActionUpdateFeatureGeometry(venue, Waze.model.venues, oldCoord, newCoord));
}
}
else
{
var oldCoord = venue.geometry.clone();
var newCoord = Waze.model.houseNumbers.objects[key].numbers[i].geometry.clone();
if ((oldCoord.x.toFixed(1) !== (newCoord.x-1).toFixed(1)) || (oldCoord.y.toFixed(1) !== newCoord.y.toFixed(1)))
{
newCoord.x--;
Waze.model.actionManager.add(new WazeActionUpdateFeatureGeometry(venue, Waze.model.venues, oldCoord, newCoord));
}
}
}
if(number.indexOf("/") !== -1 || hasChar(number))
hasRH = true;
}
if(!venue.isPoint() && document.getElementById('_updatePlaces').checked)
{
if(venue.geometry.intersects(Waze.model.houseNumbers.objects[key].numbers[i].geometry))
{
var state = updateLandmark(venue, address.city.attributes.name, address.street.name, number);
hasPOI = (hasPOI) ? hasPOI : state[0];
hasRH = (hasRH) ? hasRH : state[1];
}
}
}
console.log(number, address.street.name, "hasPOI: " + hasPOI, "hasRH: " + hasRH);
if(!hasPOI && document.getElementById('_createPOI').checked)
{
createPOI(
{
x: Waze.model.houseNumbers.objects[key].numbers[i].geometry.x,
y: Waze.model.houseNumbers.objects[key].numbers[i].geometry.y,
streetName: address.street.name,
houseNumber: number,
cityName: address.city.attributes.name
}, false);
}
if(!hasRH && document.getElementById('_createRH').checked)
{
createPOI(
{
x: Waze.model.houseNumbers.objects[key].numbers[i].geometry.x,
y: Waze.model.houseNumbers.objects[key].numbers[i].geometry.y,
streetName: address.street.name,
houseNumber: number,
cityName: address.city.attributes.name
}, true);
}
}
}
}
}, 3000);
}
function updateLandmark(venue, cityName, streetName, number)
{
var hasPOI = false;
var hasRH = false;
console.log('Обновление контура', number, streetName);
if(venue.getAddress().attributes.street.name != streetName
|| venue.getAddress().attributes.houseNumber != number
|| venue.attributes.name != number
// || venue.attributes.name.indexOf(number) === -1
|| (document.getElementById('_updateLock').checked && venue.attributes.lockRank < document.getElementById('_lockLevel').selectedIndex)
)
{
hasPOI = true;
var newAddressAtts = {
streetName: streetName,
emptyStreet: false,
cityName: (address.city.attributes.name.indexOf(cityName) != -1) ? address.city.attributes.name : cityName,
emptyCity: false,
stateID: address.state.id,
countryID: address.country.id
};
Waze.model.actionManager.add(new wazeActionUpdateFeatureAddress(venue, newAddressAtts,
{
streetIDField: 'streetID'
}));
var newAtts = {};
var haveChanges = false;
if(venue.attributes.houseNumber != number.toString() && number.indexOf(" ") == -1)
{
newAtts.houseNumber = number;
haveChanges = true;
}
if(/*venue.attributes.name.indexOf(number) === -1 ||*/ venue.attributes.name === "")
{
newAtts.name = number;
haveChanges = true;
}
var aliases = venue.attributes.aliases;
if(hasChar(number))
{
hasRH = true;
var length = venue.attributes.aliases.length;
var street = number + " " + streetName;
var hasAliasAddress = false;
for(var ia = 0; ia < length; ia++)
{
if(street == venue.attributes.aliases[ia])
{
hasAliasAddress = true;
}
}
if(!hasAliasAddress)
{
aliases.push(street);
haveChanges = true;
}
if((address.country.id == 37 || address.country.id == 186) && number.indexOf("/") != -1)
{
hasAliasAddress = false;
var street = number.replace('/', 'к') + " " + streetName;
for(var ia = 0; ia < length; ia++)
{
if(street == venue.attributes.aliases[ia])
{
hasAliasAddress = true;
}
}
if(!hasAliasAddress)
{
aliases.push(street);
haveChanges = true;
}
hasAliasAddress = false;
var street = number.replace('/', ' корпус ') + " " + streetName;
for(var ia = 0; ia < length; ia++)
{
if(street == venue.attributes.aliases[ia])
{
hasAliasAddress = true;
}
}
if(!hasAliasAddress)
{
aliases.push(street);
haveChanges = true;
}
}
}
if(haveChanges)
{
newAtts.aliases = aliases;
newAtts.lockRank = document.getElementById('_lockLevel').selectedIndex;
Waze.model.actionManager.add(new wazeActionUpdateObject(venue, newAtts));
}
}
return [hasPOI, hasRH];
}
function addAltNames(arr)
{
if($('.alias-name').length > 0)
{
$("#landmark-edit-general .aliases-view .delete").click();
}
for(var i = 0; i < arr.length; i++)
{
$("#landmark-edit-general .aliases-view .add").click();
var elem;
$('#landmark-edit-general .aliases-view input[type=text]').each(function(index) {
if(i == index) { elem = $(this); }
});
elem.val(arr[i]);
elem.change();
}
}
function isChar(number)
{
var reg = /([0-9])[А-Яа-я]/;
switch(true)
{
case reg.test(number):
return true;
default:
return false;
}
}
function hasChar(number)
{
var reg = /[а-яА-Яa-zA-Z/-]/;
switch(true)
{
case reg.test(number):
return true;
default:
return false;
}
}
function getElementsByClassName(classname, node) {
if(!node)
node = document.getElementsByTagName("body")[0];
var a = [];
var re = new RegExp('\\b' + classname + '\\b');
var els = node.getElementsByTagName("*");
for (var i=0,j=els.length; i<j; i++)
if (re.test(els[i].className)) a.push(els[i]);
return a;
}
}
altAddress_bootstrap();