Mission:Make interface able to edit polygon

Goal:Create polygon with edit interface

Step1. Create Polygon

Lets define polygon of 3 points

var verticles=[new GLatLng(37.4419     , -122.1419),
new GLatLng(37.4419+0.03, -122.1419),
new GLatLng(37.4419     , -122.1419+0.03)]

myPoly = new myEditablePolygon(verticles,map);
myPoly.attachClickEvent();
myPoly.draw();

What next?
Next - we need to edit it. Drag edge markers, create new, and delete unused
And i`ll present THREE variants of editor. In one box :)

bla-bla-bla.. lets go down to mathematics

Step2. Determine where we click, and place to add new point

Algorithm is the same as in article about polygon reduce
Take the point, find distance from it to all segments of polygon and add new verticle in right place!
So tranform it to screen space

/* transform polygon and click point to screen space */
var screen=this.mapper.toScreenSpace(set);
var point =this.mapper.toScreenSpace([pt])[0];
//and add first point as last point
var L=set.length;
screen.push(screen[0]);

And find that point!

var minval=10000000;
var minfit=-1;
var x2=point.x;
var y2=point.y;
var i;
for( i=0;i<L;i++){
//remeber the milk!
/** same login. find distance from point to segment */
var x1=screen[i].x;
var y1=screen[i].y;

var x3=screen[i+1].x;
var y3=screen[i+1].y;

var vx1=x2-x1;
var vy1=y2-y1;
var len=Math.sqrt(vy1*vy1+vx1*vx1);

var v1=this._norm(vx1,vy1,len);

var vx2=x3-x1;
var vy2=y3-y1;
var len2=Math.sqrt(vy2*vy2+vx2*vx2);
//if distance to test point is greater that distance to other side of the egde - skip
if(len>len2){
continue;
}
var v2=this._norm(vx2,vy2);

var dot=this._dot(v1,v2);
var angle=(Math.acos(dot));
/** we need positive angle and not greater that 60 degress*/
if(angle>Math.PI/3)continue;
var sa=Math.sin(angle);

var perp=sa*len;
// so this is best fit for point
if(perp<minval){
minval=perp;
minfit=i;
}
}
//and distance must be not very big
if(minval<50){
return minfit;
}
return -1;

Done, all other work you can see by yourself in scripts

Step3. Delete Verticle

just click the marker :)

online version, you can drag markers and you must CLICK the map near edge to spawn new verticle

_this.newMarker(point,'auto');
});

online version, you can drag markers and just move mouse over edge to create new verticle.
if you click spawned marker - it become normal. So variant like one you can see on wikimapia.org

if(!point)return;
//get current point and move it by 30 pixel to bottom
var sx=_this.mapper.toScreenSpace([point])[0];
sx.y+=30;
point=_this.mapper.toMapSpace([sx])[0]
//remove old marker
if(_this.dragMarker){
_this.removeHold(_this.dragMarker.holdpoint);
_this.map.removeOverlay(_this.dragMarker);
delete _this.dragMarker;
}
//find where we can(if we can) place new marker
var position=_this.findBestPosition(point);
if(position<-1)return;
else{
//and place it!
var marker=_this.newMarker(point,'auto');
_this.dragMarker=marker;
}
});

online version, you can drag markers and.. hm who add green markers where?
How i do it? Just perform some preprocess before render

myEditablePolygon.prototype.preprocess = function(){
this.removeGhosts();
this.ghostMarkers=[];
var i=0;
var verts=[];
var inverts=this.verticles.slice(0);
var L=inverts.length;
inverts.push(inverts[0]);
// lets to trought verticles and create some markers in middle of edges
for ( i=0;i<L;i++){
var _this=this;
(function(){
var x1=inverts[i]._x;
var y1=inverts[i]._y;
var x2=inverts[i+1]._x;
var y2=inverts[i+1]._y;
var point = new GLatLng(x1+(x2-x1)/2,y1+(y2-y1)/2);

var blueIcon = new GIcon(G_DEFAULT_ICON);

var marker = new GMarker(point, {draggable: true,icon:blueIcon});
marker.parent=_this;
_this.ghostMarkers.push(marker);

//on mouse down - remove blue marker and create new normal marker
this.parent.map.removeOverlay(this);
this.parent.newMarker(this.getPoint(),'auto')
});
})();
}
return this.verticles;
}
Homework: inherit from smartPolygon to perform more complex solution

All of sections, i list here, is allready done by me. I need just to wrap code into article, and, yap, english article :)
If you want to know more - ask

lest make a Very simple polygon editor

 – Идиот! – весело сказал Кащей.Мышцы радостно запели, настраиваясь на сражение. – Делать котлеты – это мое призвание! Дмитрий Мансуров