// ==UserScript==
// @name WME Alinhador e simplificador para segmentos de ruas retas
// @version 0.94
// @description Adiciona um botão no WME para simplificar a tarefa de alinhar segmentos de rua em uma reta.
// @author jonny3D, Rômulo Nunes
// @match https://*.waze.com/*editor*
// @match https://editor-beta.waze.com/*
// @match https://beta.waze.com/*
// @exclude https://www.waze.com/user/*editor/*
// @exclude https://www.waze.com/*/user/*editor/*
// @grant none
// @namespace https://greasyfork.org/users/161049
// ==/UserScript==
setTimeout(AlignStreetGeometry, 1999);
function AlignStreetGeometry() {
var UpdateSegmentGeometry = window.require("Waze/Action/UpdateSegmentGeometry");
var MoveNode = window.require("Waze/Action/MoveNode");
var AddNode = window.require("Waze/Action/AddNode");
var MultiAction = window.require("Waze/Action/MultiAction");
// multiaction.setModel(Waze.model);
window.W.selectionManager.events.register("selectionchanged", null, insertAlignStreetGeometryButtons);
var nodestrabalhados_max = 30;
var nodestrabalhados = [nodestrabalhados_max-1]; //guarda os nós já trabalhados para o alinhamento para verificar se o segmento está invertido no meio dos outros A -B ou B- A
var retaprincipal_ID_ponta_A = 0; //guarda o nó de T1
var retaprincipal_ID_ponta_B = 0; //guarda o nó de T2
var nodestrabalhados_i = 0;
var Frases = {
BR: {'btn': 'Alinhar Rua', 'msg':'Iniciando algoritmo...' }, // Brazil
FR: {'btn': 'Aligner la rue', 'msg':'Algorithme de départ...' }, // France
RS: {'btn': 'Выровнять улицу', 'msg':'Алгоритм запуска...' }, // Russia
SP: {'btn': 'Alinear la calle', 'msg':'Inicio de Algoritmo...' }, // Spain
PO: {'btn': 'Alinhar Rua', 'msg':'Iniciando algoritmo...' }, // Portugal
UY: {'btn': 'Alinear la calle', 'msg':'Inicio de Algoritmo...' }, // Uruguay
US: {'btn': 'Align Street', 'msg':'Starting Algorithm...' }, // United States
CA: {'btn': 'Align Street', 'msg':'Starting Algorithm...' }, // Canada
AR: {'btn': 'Alinear la calle', 'msg':'Inicio de Algoritmo...' }, // Argentina
PA: {'btn': 'Alinear la calle', 'msg':'Inicio de Algoritmo...' }, // Paraguay
IL: {'btn': 'רחוב ישר', 'msg':'הפעלת אלגוריתם...' } // Israel
};
function insertAlignStreetGeometryButtons()
{
// essa função vai pegar o país do mapa de onde se está editando. Se não estiver na lista acima, fica em inglês.
var FrasesNaLingua = Frases[window.W.model.countries.top.abbr];
if (typeof FrasesNaLingua == 'undefined')
{
FrasesNaLingua = Frases['US'];
console.log("WME-ASSRR: ERRO no Cod País:" + window.W.model.countries.top.abbr);
}
const BottonExiste = document.getElementById("AlignStreetGeometry");
if (!BottonExiste) {
$('.edit-restrictions').after('  <button id="AlignStreetGeometry" class="waze-btn waze-btn-small waze-btn-white">' + FrasesNaLingua.btn +'</button>');
}
}
$('#sidebar').on('click', '#AlignStreetGeometry', function(event) {
event.preventDefault();
DoAlignStreetGeometry();
});
function DoAlignStreetGeometry() {
console.log("WME-ASSRR ========================================================================================" );
console.log("WME-ASSRR I N I C I O D O A L G O R I T M O D E A L I N H A M E N T O" );
console.log("WME-ASSRR ========================================================================================" );
if (window.W.selectionManager.getSelectedFeatures().length > 0) {
var T1, T2,
t;
// A = 0.0,
// B = 0.0,
// C = 0.0;
var correct = true;
nodestrabalhados_i = 0;
for (var e0=0; e0 <= nodestrabalhados_max-1; e0++)
{
nodestrabalhados[e0] = 0;
} //iniciando a memória para os nós visitados.
console.log("WME-ASSRR: Limpeza da memória OK");
// define a linha de alinhamento
// Waze.selectionManager.getSelectedFeature.length
if (window.W.selectionManager.getSelectedFeatures().length > 0) {
//if (W.selectionManager.selectedItems.length > 0) {
console.log("WME-ASSRR: Inicio do cálculo da reta principal... (Percorrendo os segmentos)");
for (var e = 0; e < window.W.selectionManager.getSelectedFeatures().length; e++) {
var segment = window.W.selectionManager.getSelectedFeatures()[e];
if (segment.model.type != "segment")
{
continue;
}
var geometry = segment.model.geometry;
// determine a fórmula da linha inclinada
if (geometry.components.length > 1)
{
//Existem duas formas de pegar um nó. A primeira através das extremidades do segmento. A segunda pegando os nós "from" e "to" do segmento.
var nodeID_A = segment.model.attributes.fromNodeID;
var nodeID_B = segment.model.attributes.toNodeID;
//var A1 = geometry.components[0].clone();
//var A2 = geometry.components[geometry.components.length - 1].clone();
var nodeA1 = window.W.model.nodes.get(nodeID_A);
var nodeA2 = window.W.model.nodes.get(nodeID_B);
var A1 = nodeA1.geometry.clone();
var A2 = nodeA2.geometry.clone();
var flagJaIncluidoA = 0;
var flagJaIncluidoB = 0;
for (e0 = 0; e0 <= nodestrabalhados_i; e0++)
{
console.log("Contador e0: " + e0);
if (nodestrabalhados[e0] == nodeID_A)
{
flagJaIncluidoA = 1 ;
continue;
}
else if (nodestrabalhados[e0] == nodeID_B)
{
flagJaIncluidoB = 1 ;
continue;
}
}
if (flagJaIncluidoA == 0)
{
nodestrabalhados[nodestrabalhados_i++] = nodeID_A;
}
if (flagJaIncluidoB == 0)
{
nodestrabalhados[nodestrabalhados_i++] = nodeID_B;
}
console.log("");
console.log("IDs dos Nós da reta principal: " + nodestrabalhados );
console.log("WME-ASSRR========================================================================================" );
console.log("WME-ASSRR: segmento #" + (e) + " A1(" + A1.x + "; " + A1.y + "), A2(" + A2.x + "; " + A2.y + ")");
console.log("WME-ASSRR: Ponto A: " + nodeID_A +", Ponto B: " + nodeID_B );
// Preciso saber como o segmento está no plano 2D, pra determinar quais extremidades pegar.
// não dá pra pegar qualquer nó fixo porque os segmentos podem estar juntos e invertidos B --> A com um A --> B.
var delta = GetDeltaDirectPlanar(A1.x,A1.y, A2.x, A2.y);
if (delta < 0) // Se os Pontos A e B estiverem invertidos, desinverto. De forma que sempre A1 tenha a menor distancia pra p eixo 0
{
t = A1.x;
A1.x = A2.x;
A2.x = t;
t = A1.y;
A1.y = A2.y;
A2.y = t;
var t2 = nodeID_A;
nodeID_A = nodeID_B;
nodeID_B = t2;
delta = GetDeltaDirectPlanar(A1.x, A1.y, A2.x, A2.y); //pra atualizar o valor dX e dY caso tenha invertido.
console.log("WME-ASSRR: Houve ajuste no segmento #" + (e) +". Ficou agora...") ;
console.log("WME-ASSRR: segmento #" + (e) + " A1(" + A1.x + "; " + A1.y + "), A2(" + A2.x + "; " + A2.y + ")");
console.log("WME-ASSRR: Ponto A: " + nodeID_A +", Ponto B: " + nodeID_B );
}
if (e === 0) //primeiro passo da iteração, apenas guardo os dois pontos.
{
T1 = A1.clone();
T2 = A2.clone();
retaprincipal_ID_ponta_A = nodeID_A;
retaprincipal_ID_ponta_B = nodeID_B;
} else { // nos seguintes, apenas expando o ponto final de X, unindo-o na frente ou atrás. a2 ------- a1 // t2 ------ t1
var deltaA1T1 = GetDeltaDirectPlanar(A1.x, A1.y, T1.x, T1.y);
var deltaA2T2 = GetDeltaDirectPlanar(A2.x, A2.y, T2.x, T2.y);
//console.log("WME-ASSRR: Delta de A1 e T1: " + deltaA1T1);
//console.log("WME-ASSRR: Delta de A2 e T2: " + deltaA2T2);
if (deltaA1T1 > 0) // se encontrei um nó menor que o já existente em T1.
{
T1.x = A1.x;
T1.y = A1.y;
retaprincipal_ID_ponta_A = nodeID_A;
//console.log("WME-ASSRR: Alterado T1");
}
if (deltaA2T2 < 0) // se encontrei um nó maior que o já existente em T2. Não usar else no if anterior porque os segmetnos não são em sequncia
{
T2.x = A2.x;
T2.y = A2.y;
retaprincipal_ID_ponta_B = nodeID_B;
//console.log("WME-ASSRR: Alterado T2");
}
}
console.log("WME-ASSRR: Reta Parcial: T1 (" + T1.x + "; " + T1.y + ") , T2 (" + T2.x + "; " + T2.y + ")");
console.log("WME-ASSRR: IDs dos nós: T1 ("+retaprincipal_ID_ponta_A+") , T2 (" +retaprincipal_ID_ponta_B + ")");
//console.log("WME-ASSRR: IDs dos nós: T1 ("+retaprincipal_ID_ponta_A+") , T2 (" +retaprincipal_ID_ponta_B + ")");
}
}
// Dada a reta calculada acima (ponto inicial da rua e ponto fina) da rua que se quer alinar,
// precisamos calcular os novos pontos de interseção com a retas das ruas que se conectam a rua alinhada.
// o alinhamento se dá pelos novos pontos de interseção.
// Essa é a função da primeira reta.
//A = T2.y - T1.y;
//B = T1.x - T2.x;
//C = T2.x * T1.y - T1.x * T2.y;
console.log("WME-ASSRR: =====================================================================================");
console.log("WME-ASSRR: Reta final calculada: T1 (" + T1.x + ";" + T1.y + ") - T2 (" + T2.x + ";" + T2.y + ")");
console.log("WME-ASSRR: IDs dos nós: T1 ("+retaprincipal_ID_ponta_A+") , T2 (" +retaprincipal_ID_ponta_B + ")");
console.log("WME-ASSRR: =====================================================================================");
console.log("" );
// desenhe uma linha de controle
/*var seg1geo = segment.model.geometry;
if (seg1geo.components.length > 2)
seg1geo.components.splice(1, seg1geo.components.length - 2);
seg1geo.comments[0].x = T1.x;
seg1geo.comments[0].y = T1.y;
seg1geo.comments[1].x = T2.x;
seg1geo.comments[1].y = T2.y;
var newseg1 = new Waze.Feature.Vector.Segment(seg1geo);
newseg1.attributes.fromNodeID = null;
newseg1.attributes.toNodeID = null;
Waze.model.actionManager.add(new Waze.Action.AddSegment(newseg1));
*/
} else
{correct = false;}
if (correct) // correct
{
console.log("");
// remover nós desnecessários (simplificando segmentos)
for (var e2 = 0; e2 < window.W.selectionManager.getSelectedFeatures().length; e2++)
{
var segment2 = window.W.selectionManager.getSelectedFeatures()[e2];
var model = segment2.model;
if (model.type != "segment")
{
continue;
}
console.log("WME-ASSRR Percorrendo seleção para simplificar... Segmento #"+ (e2 + 1) + " =======================================" );
var newGeometry = model.geometry.clone();
var flagSimpled = false;
if (newGeometry.components.length > 2)
{
newGeometry.components.splice(1, newGeometry.components.length - 2);
flagSimpled = true;
}
if (flagSimpled)
{
window.W.model.actionManager.add(new UpdateSegmentGeometry(model, model.geometry, newGeometry));
}
}
console.log("");
console.log("WME-ASSRR: Início da etapa para alinhar segmentos...");
for (e2 = 0; e2 < nodestrabalhados_i; e2++ ) //percorrer toda a seleção
{
// trabalhar com o nó para encontrar o nó vizinho da reta adjacente.
//decidir qual nó do segmento trabalhar, pegando o fromNodeID ou toNodeID, conforme o caso.
console.log("" );
console.log("WME-ASSRR Percorrendo seleção para alinhar... >>>>>>>>>>>> SEGMENTO #"+ (e2) + " Nó #" + nodestrabalhados[e2] + " <<<<<<<<<< " );
var node = window.W.model.nodes.get(nodestrabalhados[e2]);
var nodeGeo = node.geometry.clone();
console.log("WME-ASSRR ID Atual: " + nodestrabalhados[e2] );
//console.log("WME-ASSRR Nó.x na lista: " + nodeGeo.x );
//console.log("WME-ASSRR T1.x na reta: " + T1.x );
//console.log("WME-ASSRR Nó.y na lista: " + nodeGeo.y );
//console.log("WME-ASSRR T1.y na reta: " + T1.y );
var procurar = true;
//verificando se o dó é da extreminade para não atualizar.
//if ((nodeGeo.x == T1.x) & (nodeGeo.y == T1.y))
if ((nodestrabalhados[e2] == retaprincipal_ID_ponta_A))
{
console.log("WME-ASSRR: Nó da extremidade A... ABORTAR ALINHAMENTO DESSE NÓ" );
procurar = false;
}
else if ((nodestrabalhados[e2] == retaprincipal_ID_ponta_B))
{
console.log("WME-ASSRR: Nó da extremidade B... ABORTAR ALINHAMENTO DESSE NÓ" );
procurar = false;
}
var node2 = node;
var nodeGeo2 = node2.geometry.clone();
console.log("");
console.log("WME-ASSRR: PERCORRENDO SEGMENTOS QUE PERTENCEM AO MESMO NÓ (ID " + nodestrabalhados[e2] + ")");
console.log("WME-ASSRR: Num de segmentos: " + node2.attributes.segIDs.length); //número de segmentos do nó.
console.log("WME-ASSRR: Nó de intersecção: " + nodeGeo); //nó usado para busca
var RetaAjuste_PontoB = nodeGeo.clone(); //inicializando a variável com o mesmo ponto da origem da reta
var encontrouRetaADJ = false;
var j = 0;
//percorre todos os segmentos que pertencem ao nó. Devemos parar quando encontrar um nó adj.
while((j<node2.attributes.segIDs.length) & (encontrouRetaADJ == false) & (procurar == true))
{
//console.log("WME-ASSRR: loop: " + j);
var SegRetaID = node2.attributes.segIDs[j]; //ID de uma Reta com esse Nó
var SegReta = window.W.model.segments.get(SegRetaID); //a reta dona do ID
var SegReta_geo = SegReta.geometry.clone();
var SegReta_A_ID = SegReta.attributes.fromNodeID;
//console.log("WME-ASSRR: from: " + SegReta_A_ID);
var SegReta_B_ID = SegReta.attributes.toNodeID;
//console.log("WME-ASSRR: to: " + SegReta_B_ID);
var nodeXY = window.W.model.nodes.get(SegReta_B_ID); //inicializo
var nodeXYGeo = nodeXY.geometry.clone();
//se apenas o nó A for encontrado, então o segmento AB é adjacente à reta principal
if (NoDaRetaPrincipal(SegReta_A_ID) & ! NoDaRetaPrincipal(SegReta_B_ID))
{
//nodeXY = Waze.model.nodes.get(SegReta_B_ID);
//nodeXYGeo = nodeXY.geometry.clone();
RetaAjuste_PontoB = nodeXYGeo.clone(); //guardo o nó para usar
encontrouRetaADJ = true;
//console.log("WME-ASSR Reta ADJ com B");
} //se apenas o nó B for encontrado, então o segmento AB é adjacente à reta principal
else if (NoDaRetaPrincipal(SegReta_B_ID) & ! NoDaRetaPrincipal(SegReta_A_ID))
{
nodeXY = window.W.model.nodes.get(SegReta_A_ID);
nodeXYGeo = nodeXY.geometry.clone();
RetaAjuste_PontoB = nodeXYGeo.clone();
encontrouRetaADJ = true;
//console.log("WME-ASSR Reta ADJ com A");
}
j++;
}
//Refs. bibliográficas sobre a função de interseção:
//1. http://www.inf.pucrs.br/~pinho/CG/Aulas/OpenGL/Interseccao/CalcIntersec.html
//2. John Vince, Geometry for Computer Graphics, Springer, 2005
//3. http://www.dpi.inpe.br/livros/bdados/cap2.pdf (Melhor pra entender )
if (encontrouRetaADJ == true)
{
// Apresentando a reta ADJ encontrada para o calculo do ponto de intersecção.
console.log("WME-ASSRR: Reta ADJ encontrada:");
var S1 = nodeGeo.clone();
var S2 = RetaAjuste_PontoB.clone();
console.log("WME-ASSRR: Origem: " + S1);
console.log("WME-ASSRR: Fim: " + S2);
////////////////////////////////////////////////////////////////////////////////////////////////////
//Método de cálculo usando a função GetIntersectLinesInt, que usa as funções gerais das retas.
/*var P_intersec = GetIntersectLinesInt(T1.x, T1.y, T2.x , T2.y, S1.x, S1.y, S2.x, S2.y);
//nodeGeo2.x = P_intersec[0];
nodeGeo2.y = P_intersec[1];*/
/////////////////////////////////////////////////////////////////////////////////////////////////////
//Médodo de cálculo que usa a interseção de segmentos.
//Temos as retas dadas pelos pontos T1 e T2 (reta principal) e S1 e S2 reta adj).
// k l m n
// 1 2 3 4
//var determinante = ((S2.x - S1.x) * (T2.y - T1.y)) - (( S2.y - S1.y) * (T2.x - T1.x));
var determinante = ((S2.y - S1.y) * (T2.x - T1.x)) - (( S2.x - S1.x) * (T2.y - T1.y));
if (determinante == 0) //retas paralelas
{
console.log("WME-ASSRR: Retas PARALELAS (chamar próximo)");
continue; //pegar próxima etapa no lop
}
else
{
//console.log("WME-ASSRR: Determinante: " + determinante);
// (4x - 3x) ( 1y - 3y) - (4y - 3y) (1x - 3x)
var u = (((S2.x - S1.x) * (T1.y - S1.y)) - ((S2.y - S1.y) * (T1.x - S1.x)))/ determinante;
// (2x - 1x)(1y - 3y) - (2y - 1y)(1x - 3x)
var v = (((T2.x - T1.x) * (T1.y - S1.y)) - ((T2.y - T1.y) * (T1.x - S1.x)))/ determinante;
//console.log("WME-ASSRR: u: " + u);
//console.log("WME-ASSRR: v: " + v);
if (( u >= 0 ) & ( u <= 1 ))
{
nodeGeo2.x = T1.x + u * (T2.x - T1.x ) ;
nodeGeo2.y = T1.y + u * (T2.y - T1.y ) ;
} else if (( v >= 0 ) & ( v <= 1 ))
{
nodeGeo2.x = S1.x + v * (S2.x - S1.x ) ;
nodeGeo2.y = S1.y + v * (S2.y - S1.y ) ;
} else
{
nodeGeo2 = S1.clone();
}
}
console.log("WME-ASSRR: Nó atualizado (interseção das retas): " + nodeGeo2);
//nodeGeo2.calculateBounds();
// Ajustando os segmentos adjacentes para o novo ponto do nó (novas coordenadas)
var connectedSegObjs = {}; //guardando os segmentos que pertencem ao Nó pra usar no final para mover o nó.
var connectedSegObjs_copia = {};
var connectedSegObjs_Geom = {};
var emptyObj = {};
var multiaction = new MultiAction();
multiaction.setModel(window.W.model);
for (var k = 0; k < node2.attributes.segIDs.length; k++)
{
var segid = node2.attributes.segIDs[k];
console.log("WME-ASSRR: Segmentos conectados ao Nó atual. ID " + segid );
//connectedSegObjs[segid] = node2.model.segments.get(segid).geometry.clone();
//connectedSegObjs_copia[segid] = connectedSegObjs[segid];
// ////segment.model.attributes.toNodeID;
connectedSegObjs[segid] = node2.model.segments.get(segid).clone();
connectedSegObjs_Geom[segid] = connectedSegObjs[segid].geometry.clone();
connectedSegObjs_copia[segid] = connectedSegObjs_Geom[segid];
//console.log(" " );
//var nodeA1 = Waze.model.nodes.get(nodeID_A);
//console.log("WME-ASSRR: Comp com Original: " + nodeGeo );
var conect_no_A = connectedSegObjs[segid].attributes.fromNodeID; // cpegou o id do nó
var connectedSegObjs_A = window.W.model.nodes.get(conect_no_A).geometry.clone(); // pegou o ponto do nó
//var connectedSegObjs_A = connectedSegObjs[segid].components[0].clone();
console.log("WME-ASSRR: Seg A para ajuste: " + connectedSegObjs_A );
var conect_no_B = connectedSegObjs[segid].attributes.toNodeID; // pegou o id do nó
var connectedSegObjs_B = window.W.model.nodes.get(conect_no_B).geometry.clone(); //pegou o ponto do nó..
//var connectedSegObjs_B = connectedSegObjs[segid].components[1].clone();
console.log("WME-ASSRR: Seg B para ajuste: " + connectedSegObjs_B);
//preciso encontrar o component do segmento que guarda o nó FROM
var achouiqual_from = -1;
var e6 = 0;
//console.log("WME-ASSRR: e6 A: "+ e6);
//console.log("WME-ASSRR: Tam A vetor: "+ connectedSegObjs_Geom[segid].components.length);
while (e6 < connectedSegObjs_Geom[segid].components.length)
{
//console.log("WME-ASSRR: e6: "+ e6);
if((connectedSegObjs_Geom[segid].components[e6].x == connectedSegObjs_A.x) & (connectedSegObjs_Geom[segid].components[e6].y == connectedSegObjs_A.y))
{
achouiqual_from = e6;
//console.log("WME-ASSRR: e6: Encontrou A! ");
}
e6++;
}
//preciso encontrar o component do segmento que guarda o nó FROM e o TO
var achouiqual_to = -1;
e6 = 0;
//console.log("WME-ASSRR: e6 B: "+ e6);
//console.log("WME-ASSRR: Tam B vetor: "+ connectedSegObjs_Geom[segid].components.length);
while (e6 < connectedSegObjs_Geom[segid].components.length)
{
//console.log("WME-ASSRR: e6: "+ e6);
if((connectedSegObjs_Geom[segid].components[e6].x == connectedSegObjs_B.x) & (connectedSegObjs_Geom[segid].components[e6].y == connectedSegObjs_B.y))
{
achouiqual_to = e6;
//console.log("WME-ASSRR: e6: Encontrou B! ");
}
e6++;
}
console.log("WME-ASSRR: Nó no A vetor de nós do segmento : " + achouiqual_from);
console.log("WME-ASSRR: Nó no B vetor de nós do segmento : " + achouiqual_to);
//console.log("WME-ASSRR: Nó connectedSegObjs_A : " + connectedSegObjs_A);
//console.log("WME-ASSRR: Nó connectedSegObjs_B : " + connectedSegObjs_B);
//console.log("WME-ASSRR: Nó nodeGe: " + nodeGeo);
// ajustando
if ((nodeGeo.x == connectedSegObjs_A.x) & ( nodeGeo.y == connectedSegObjs_A.y) & (achouiqual_from > -1)) //ajuste manual das retas conectadas.
{
//console.log("WME-ASSRR: Inicio set FROM. ");
connectedSegObjs_Geom[segid].components[achouiqual_from].x = nodeGeo2.x;
connectedSegObjs_Geom[segid].components[achouiqual_from].y = nodeGeo2.y;
//console.log("WME-ASSRR: Ajustou no FROM. ");
}
else if ((nodeGeo.x ==connectedSegObjs_B.x) & ( nodeGeo.y == connectedSegObjs_B.y) & (achouiqual_to > -1))
{
//console.log("WME-ASSRR: Inicio set TO. ");
connectedSegObjs_Geom[segid].components[achouiqual_to].x = nodeGeo2.x;
connectedSegObjs_Geom[segid].components[achouiqual_to].y = nodeGeo2.y;
//console.log("WME-ASSRR: Ajustou no TO. ");
}else
{ //se o nó foi "mexido sem querer" pelas etapas anteriores, teríamos a falta de conexao de um segmento.
//Basta pegar o nó do segmento mais próximo ao nó ajustado.
console.log("WME-ASSRR: Entrando da identificacao do nó pela Distância Euclidiana.");
var deltaseg = GetDeltaDirectPlanarComReferencial(connectedSegObjs_A.x,connectedSegObjs_A.y, connectedSegObjs_B.x, connectedSegObjs_B.y, nodeGeo2.x, nodeGeo2.y);
if (deltaseg > 0 )
{
connectedSegObjs_Geom[segid].components[0].x = nodeGeo2.x;
connectedSegObjs_Geom[segid].components[0].y = nodeGeo2.y;
}
else
{
connectedSegObjs_Geom[segid].components[1].x = nodeGeo2.x;
connectedSegObjs_Geom[segid].components[1].y = nodeGeo2.y;
}
}
console.log("WME-ASSRR: Ajustado A para : " + connectedSegObjs_Geom[segid].components[0]);
console.log("WME-ASSRR: Ajustado B para : " + connectedSegObjs_Geom[segid].components[1]);
multiaction.doSubAction(new UpdateSegmentGeometry(node2.model.segments.get(segid), connectedSegObjs_copia[segid] , connectedSegObjs_Geom[segid]));
//console.log("WME-ASSRR: multiaction update OK. ");
}
//console.log("flag1");
//Waze.model.actionManager.add(new MoveNode(node, node.geometry, nodeGeo2));
//Waze.model.actionManager.add(new MoveNode(node, node.geometry, nodeGeo2, connectedSegObjs, emptyObj));
nodeGeo2.calculateBounds();
//console.log("WME-ASSRR: calculate bounds OK. ");
multiaction.doSubAction(new MoveNode(node, node.geometry, nodeGeo2, connectedSegObjs_Geom, emptyObj));
//console.log("WME-ASSRR: multiaction move node OK. ");
window.W.model.actionManager.add(multiaction);
console.log("WME-ASSRR: Final do ajuste do Nó");
console.log("=====================================================================================");
}
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// F U N Ç Õ E S
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// função que recebe duas retas e devolve o ponto de intersecao.
//Fonte2: http://www.guj.com.br/t/resolvido-ponto-de-interseccao-entres-duas-retas-de-coeficiente-a1-e-b1-e-a2-e-b2/91148
//Fonte1: http://mundoeducacao.bol.uol.com.br/matematica/determinando-equacao-geral-reta.htm
function GetIntersectLines(Ax, Ay, Bx, By, Cx, Cy, Dx, Dy)
{
console.log("WME-ASSRR: Entrou na função para calculo da interseção");
var r = [2];
r[0] = 0;
r[1] = 0;
var reta1_A = Ay - By;
var reta1_B = Bx - Ax;
var reta1_C = (Ax * By) - (Bx * Ay);
var reta2_A = Cy - Dy;
var reta2_B = Dx - Cx;
var reta2_C = (Cx * Dy) - (Dx * Cy);
//equac geral Ax + By + C = 0
var coefAB = (By-Ay)/(Bx-Bx);
var coefCD = (Dy-Cy)/(Dx-Cx);
//forma reduzida
// Ax + By + C = 0
// y = (-Ax - C) / B
// y = -Ax/B -C/B
var reta1_AR = -reta1_A / reta1_B;
var reta1_BR = -reta1_C / reta1_B;
var reta2_AR = -reta2_A / reta2_B;
var reta2_BR = -reta2_C / reta2_B;
//a1 * x + b1 = a2 * x + b2
// a1 x - a2 x = b2 - b1
// x (a1 - a2) = b2 - b1
if (coefCD != coefAB) // se não forem paralelas.
{
r[0] = (reta2_BR - reta1_BR) / (reta1_AR - reta2_AR);
console.log("WME-ASSRR: calculado x " + r[0]);
r[1] = reta1_AR * r[0] + reta1_BR;
console.log("WME-ASSRR: calculado y " + r[1]);
}
return r;
}
function GetIntersectLinesInt(Ax, Ay, Bx, By, Cx, Cy, Dx, Dy)
{
console.log("WME-ASSRR: Entrou na função para calculo da interseção");
var r = [2];
r[0] = 0.0;
r[1] = 0.0;
const precisao = 11; //trabalhando com ponto flutuante limitando casas decimais.
var reta1_A = parseFloat( Ay.toFixed(precisao)) - parseFloat(By.toFixed(precisao)) ;
var reta1_B = parseFloat(Bx.toFixed( precisao)) - parseFloat(Ax.toFixed(precisao));
var reta1_C = (parseFloat(Ax.toFixed( precisao)) * parseFloat(By.toFixed(precisao))) - ( parseFloat(Bx.toFixed( precisao)) * parseFloat(Ay.toFixed( precisao)));
var reta2_A = parseFloat(Cy.toFixed(precisao)) - parseFloat(Dy.toFixed( precisao));
var reta2_B =parseFloat(Dx.toFixed(precisao)) - parseFloat(Cx.toFixed( precisao));
var reta2_C = ( parseFloat(Cx.toFixed( precisao)) * parseFloat(Dy.toFixed( precisao))) - (parseFloat(Dx.toFixed( precisao)) * parseFloat(Cy.toFixed( precisao)));
//equac geral Ax + By + C = 0
var coefAB = (parseFloat(By.toFixed( precisao))-parseFloat(Ay.toFixed( precisao))) / (parseFloat(Bx.toFixed( precisao))-parseFloat(Bx.toFixed(precisao)));
var coefCD = (parseFloat(Dy.toFixed( precisao))-parseFloat(Cy.toFixed( precisao))) / (parseFloat(Dx.toFixed( precisao))-parseFloat(Cx.toFixed( precisao)));
//forma reduzida
// Ax + By + C = 0
// y = (-Ax - C) / B
// y = -Ax/B -C/B
var reta1_AR = (-reta1_A / reta1_B);
var reta1_BR = (-reta1_C / reta1_B);
var reta2_AR = (-reta2_A / reta2_B);
var reta2_BR = (-reta2_C / reta2_B);
//a1 * x + b1 = a2 * x + b2
// a1 x - a2 x = b2 - b1
// x (a1 - a2) = b2 - b1
if (coefCD != coefAB) // se não forem paralelas.
{
r[0] = (((reta2_BR - reta1_BR) / (reta1_AR - reta2_AR)));
r[1] = (reta1_AR * r[0] + reta1_BR);
r[0] = parseFloat(r[0].toFixed(precisao));
r[1] = parseFloat(r[1].toFixed(precisao));
}
return r;
}
//mesma funcao de cima, porém sem o controle de casas decimais.
function GetIntersectCoord(A1, B1, C1, A2, B2, C2, W) {
//x:=(b1*c2 - b2*c1)/denom;
//y:=(a2*c1 - a1*c2)/denom;
var r = [2];
r[0] = 1;
r[1] = 1;
if (W != 0){
r[0] = (B1 * C2 - B2 * C1)/W;
r[1] = (A2 * C1 - A1 * C2)/W;
}
return r;
}
// define a direção da reta
function GetDeltaDirect(A, B) {
var d = 0.0;
if(A < B)
{
d = 1.0;
}
else if (A > B)
{
d = -1.0;
}
return d;
}
// define a direcao da reta atraveś da distância euclidiana em relação ao eixo de origem 0.0
function GetDeltaDirectPlanar(x1,y1, x2, y2) {
var d = 0.0;
var lado1 = Math.sqrt((x1 * x1) + (y1 * y1)); //ao quadrado pra remover o sinal
var lado2 = Math.sqrt((x2 * x2) + (y2 * y2));
console.log("WME-ASSRR: lado 1: " + lado1 );
console.log("WME-ASSRR: lado 2: " + lado2 );
if (lado1 < lado2)
{
d = 1.0;
console.log("WME-ASSRR: lado 1 é menor" );
}
else if (lado1 > lado2)
{
d = -1.0;
console.log("WME-ASSRR: lado 2 é menor" );
}
return d;
}
// define a direcao da reta atraveś da distância euclidiana em relação ao eixo de origem 0.0
function GetDeltaDirectPlanarComReferencial(x1,y1, x2, y2, ox, oy) {
var d = 0.0;
var lado1 = Math.sqrt(Math.pow(x1 - ox,2) + Math.pow(y1 - oy,2)); //ao quadrado pra remover o sinal
var lado2 = Math.sqrt(Math.pow(x2 - ox,2) + Math.pow(y2 - oy,2));
console.log("WME-ASSRR: distancia A-O: " + lado1 );
console.log("WME-ASSRR: distancia B-O: " + lado2 );
if (lado1 < lado2)
{
d = 1.0;
console.log("WME-ASSRR: lado A-O é menor" );
}
else if (lado1 > lado2)
{
d = -1.0;
console.log("WME-ASSRR: lado B-O é menor" );
}
return d;
}
function NoDaRetaPrincipal(node)
{
var r = false;
for (var e6 = 0; e6 < nodestrabalhados_i; e6++ ) //percorrer toda a seleção
{
console.log("WME-ASSRR:.. Procurando ID na reta principal. Item #"+ (e6) + "" );
if (nodestrabalhados[e6] == node)
{
r = true;
console.log("WME-ASSRR:.. Encontrado");
}
}
if (r == false)
{
console.log("WME-ASSRR:.. Não encontrado");
console.log("WME-ASSRR:.. Não encontrado Nó: " + node);
console.log("WME-ASSRR:.. Não encontrado Em: " + nodestrabalhados);
}
return r;
}
}