Skip to content

Commit 94f9fae

Browse files
authored
Holes in polygon support edit (#1190), fix #1128, fix #839
* Holes in polygon support edit * fix removeVertex
1 parent ddbf4fc commit 94f9fae

File tree

1 file changed

+88
-53
lines changed

1 file changed

+88
-53
lines changed

src/geometry/editor/GeometryEditor.js

+88-53
Original file line numberDiff line numberDiff line change
@@ -795,65 +795,76 @@ class GeometryEditor extends Eventable(Class) {
795795
const verticeLimit = shadow instanceof Polygon ? 3 : 2;
796796
const propertyOfVertexRefreshFn = 'maptalks--editor-refresh-fn',
797797
propertyOfVertexIndex = 'maptalks--editor-vertex-index';
798-
const vertexHandles = [],
799-
newVertexHandles = [];
798+
//{ ringIndex:ring }
799+
const vertexHandles = { 0: [] },
800+
newVertexHandles = { 0: [] };
800801

801-
function getVertexCoordinates() {
802+
function getVertexCoordinates(ringIndex = 0) {
802803
if (shadow instanceof Polygon) {
803-
const coordinates = shadow.getCoordinates()[0];
804+
const coordinates = shadow.getCoordinates()[ringIndex] || [];
804805
return coordinates.slice(0, coordinates.length - 1);
805806
} else {
806807
return shadow.getCoordinates();
807808
}
808809

809810
}
810811

811-
function getVertexPrjCoordinates() {
812-
return shadow._getPrjCoordinates();
812+
function getVertexPrjCoordinates(ringIndex = 0) {
813+
if (ringIndex === 0) {
814+
return shadow._getPrjCoordinates();
815+
}
816+
return shadow._getPrjHoles()[ringIndex - 1];
813817
}
814818

815819
function onVertexAddOrRemove() {
816820
//restore index property of each handles.
817-
for (let i = vertexHandles.length - 1; i >= 0; i--) {
818-
vertexHandles[i][propertyOfVertexIndex] = i;
819-
}
820-
for (let i = newVertexHandles.length - 1; i >= 0; i--) {
821-
newVertexHandles[i][propertyOfVertexIndex] = i;
821+
for (const ringIndex in vertexHandles) {
822+
for (let i = vertexHandles[ringIndex].length - 1; i >= 0; i--) {
823+
vertexHandles[ringIndex][i][propertyOfVertexIndex] = i;
824+
}
825+
for (let i = newVertexHandles[ringIndex].length - 1; i >= 0; i--) {
826+
newVertexHandles[ringIndex][i][propertyOfVertexIndex] = i;
827+
}
822828
}
823829
me._updateCoordFromShadow();
824830
}
825831

826832
function removeVertex(param) {
827833
const handle = param['target'],
828834
index = handle[propertyOfVertexIndex];
829-
const prjCoordinates = getVertexPrjCoordinates();
835+
const ringIndex = isNumber(handle._ringIndex) ? handle._ringIndex : 0;
836+
const prjCoordinates = getVertexPrjCoordinates(ringIndex);
830837
if (prjCoordinates.length <= verticeLimit) {
831838
return;
832839
}
833840
prjCoordinates.splice(index, 1);
834-
shadow._setPrjCoordinates(prjCoordinates);
841+
if (ringIndex > 0) {
842+
shadow._prjHoles[ringIndex - 1] = prjCoordinates;
843+
} else {
844+
shadow._setPrjCoordinates(prjCoordinates);
845+
}
835846
shadow._updateCache();
836847
//remove vertex handle
837-
vertexHandles.splice(index, 1)[0].remove();
848+
vertexHandles[ringIndex].splice(index, 1)[0].remove();
838849
//remove two neighbor "new vertex" handles
839-
if (index < newVertexHandles.length) {
840-
newVertexHandles.splice(index, 1)[0].remove();
850+
if (index < newVertexHandles[ringIndex].length) {
851+
newVertexHandles[ringIndex].splice(index, 1)[0].remove();
841852
}
842853
let nextIndex;
843854
if (index === 0) {
844-
nextIndex = newVertexHandles.length - 1;
855+
nextIndex = newVertexHandles[ringIndex].length - 1;
845856
} else {
846857
nextIndex = index - 1;
847858
}
848-
newVertexHandles.splice(nextIndex, 1)[0].remove();
859+
newVertexHandles[ringIndex].splice(nextIndex, 1)[0].remove();
849860
//add a new "new vertex" handle.
850-
newVertexHandles.splice(nextIndex, 0, createNewVertexHandle.call(me, nextIndex));
861+
newVertexHandles[ringIndex].splice(nextIndex, 0, createNewVertexHandle.call(me, nextIndex, ringIndex));
851862
onVertexAddOrRemove();
852863
me._refresh();
853864
}
854865

855-
function moveVertexHandle(handleViewPoint, index) {
856-
const vertice = getVertexPrjCoordinates();
866+
function moveVertexHandle(handleViewPoint, index, ringIndex = 0) {
867+
const vertice = getVertexPrjCoordinates(ringIndex);
857868
const nVertex = map._viewPointToPrj(handleViewPoint);
858869
const pVertex = vertice[index];
859870
pVertex.x = nVertex.x;
@@ -863,30 +874,30 @@ class GeometryEditor extends Eventable(Class) {
863874
me._updateCoordFromShadow(true);
864875
let nextIndex;
865876
if (index === 0) {
866-
nextIndex = newVertexHandles.length - 1;
877+
nextIndex = newVertexHandles[ringIndex].length - 1;
867878
} else {
868879
nextIndex = index - 1;
869880
}
870881
//refresh two neighbor "new vertex" handles.
871-
if (newVertexHandles[index]) {
872-
newVertexHandles[index][propertyOfVertexRefreshFn]();
882+
if (newVertexHandles[ringIndex][index]) {
883+
newVertexHandles[ringIndex][index][propertyOfVertexRefreshFn]();
873884
}
874-
if (newVertexHandles[nextIndex]) {
875-
newVertexHandles[nextIndex][propertyOfVertexRefreshFn]();
885+
if (newVertexHandles[ringIndex][nextIndex]) {
886+
newVertexHandles[ringIndex][nextIndex][propertyOfVertexRefreshFn]();
876887
}
877888
}
878889

879-
function createVertexHandle(index) {
880-
let vertex = getVertexCoordinates()[index];
890+
function createVertexHandle(index, ringIndex = 0) {
891+
let vertex = getVertexCoordinates(ringIndex)[index];
881892
const handle = me.createHandle(vertex, {
882893
'symbol': me.options['vertexHandleSymbol'],
883894
'cursor': 'pointer',
884895
'axis': null,
885896
onMove: function (handleViewPoint) {
886-
moveVertexHandle(handleViewPoint, handle[propertyOfVertexIndex]);
897+
moveVertexHandle(handleViewPoint, handle[propertyOfVertexIndex], ringIndex);
887898
},
888899
onRefresh: function () {
889-
vertex = getVertexCoordinates()[handle[propertyOfVertexIndex]];
900+
vertex = getVertexCoordinates(ringIndex)[handle[propertyOfVertexIndex]];
890901
handle.setCoordinates(vertex);
891902
},
892903
onUp: function () {
@@ -900,12 +911,13 @@ class GeometryEditor extends Eventable(Class) {
900911
}
901912
});
902913
handle[propertyOfVertexIndex] = index;
914+
handle._ringIndex = ringIndex;
903915
handle.on(me.options['removeVertexOn'], removeVertex);
904916
return handle;
905917
}
906918

907-
function createNewVertexHandle(index) {
908-
let vertexCoordinates = getVertexCoordinates();
919+
function createNewVertexHandle(index, ringIndex = 0) {
920+
let vertexCoordinates = getVertexCoordinates(ringIndex);
909921
let nextVertex;
910922
if (index + 1 >= vertexCoordinates.length) {
911923
nextVertex = vertexCoordinates[0];
@@ -921,42 +933,46 @@ class GeometryEditor extends Eventable(Class) {
921933
if (e && e.domEvent && e.domEvent.button === 2) {
922934
return;
923935
}
924-
const prjCoordinates = getVertexPrjCoordinates();
936+
const prjCoordinates = getVertexPrjCoordinates(ringIndex);
925937
const vertexIndex = handle[propertyOfVertexIndex];
926938
//add a new vertex
927939
const pVertex = projection.project(handle.getCoordinates());
928940
//update shadow's vertice
929941
prjCoordinates.splice(vertexIndex + 1, 0, pVertex);
930-
shadow._setPrjCoordinates(prjCoordinates);
942+
if (ringIndex > 0) {
943+
//update hole
944+
shadow._prjHoles[ringIndex - 1] = prjCoordinates;
945+
} else {
946+
shadow._setPrjCoordinates(prjCoordinates);
947+
}
931948
shadow._updateCache();
932949

933950
const symbol = handle.getSymbol();
934951
delete symbol['opacity'];
935952
handle.setSymbol(symbol);
936953

937954
//add two "new vertex" handles
938-
newVertexHandles.splice(vertexIndex, 0, createNewVertexHandle.call(me, vertexIndex), createNewVertexHandle.call(me, vertexIndex + 1));
939-
955+
newVertexHandles[ringIndex].splice(vertexIndex, 0, createNewVertexHandle.call(me, vertexIndex, ringIndex), createNewVertexHandle.call(me, vertexIndex + 1, ringIndex));
940956
},
941957
onMove: function (handleViewPoint) {
942-
moveVertexHandle(handleViewPoint, handle[propertyOfVertexIndex] + 1);
958+
moveVertexHandle(handleViewPoint, handle[propertyOfVertexIndex] + 1, ringIndex);
943959
},
944960
onUp: function (e) {
945961
if (e && e.domEvent && e.domEvent.button === 2) {
946962
return;
947963
}
948964
const vertexIndex = handle[propertyOfVertexIndex];
949965
//remove this handle
950-
removeFromArray(handle, newVertexHandles);
966+
removeFromArray(handle, newVertexHandles[ringIndex]);
951967
handle.remove();
952968
//add a new vertex handle
953-
vertexHandles.splice(vertexIndex + 1, 0, createVertexHandle.call(me, vertexIndex + 1));
969+
vertexHandles[ringIndex].splice(vertexIndex + 1, 0, createVertexHandle.call(me, vertexIndex + 1, ringIndex));
954970
onVertexAddOrRemove();
955971
me._updateCoordFromShadow();
956972
me._refresh();
957973
},
958974
onRefresh: function () {
959-
vertexCoordinates = getVertexCoordinates();
975+
vertexCoordinates = getVertexCoordinates(ringIndex);
960976
const vertexIndex = handle[propertyOfVertexIndex];
961977
let nextIndex;
962978
if (vertexIndex === vertexCoordinates.length - 1) {
@@ -971,23 +987,42 @@ class GeometryEditor extends Eventable(Class) {
971987
handle[propertyOfVertexIndex] = index;
972988
return handle;
973989
}
974-
const vertexCoordinates = getVertexCoordinates();
975-
for (let i = 0, len = vertexCoordinates.length; i < len; i++) {
976-
vertexHandles.push(createVertexHandle.call(this, i));
977-
if (i < len - 1) {
978-
newVertexHandles.push(createNewVertexHandle.call(this, i));
979-
}
980-
}
981990
if (shadow instanceof Polygon) {
982-
//1 more vertex handle for polygon
983-
newVertexHandles.push(createNewVertexHandle.call(this, vertexCoordinates.length - 1));
991+
const rings = shadow.getHoles().length + 1;
992+
for (let ringIndex = 0; ringIndex < rings; ringIndex++) {
993+
vertexHandles[ringIndex] = [];
994+
newVertexHandles[ringIndex] = [];
995+
const vertexCoordinates = getVertexCoordinates(ringIndex);
996+
for (let i = 0, len = vertexCoordinates.length; i < len; i++) {
997+
vertexHandles[ringIndex].push(createVertexHandle.call(this, i, ringIndex));
998+
if (i < len - 1) {
999+
newVertexHandles[ringIndex].push(createNewVertexHandle.call(this, i, ringIndex));
1000+
}
1001+
}
1002+
//1 more vertex handle for polygon
1003+
newVertexHandles[ringIndex].push(createNewVertexHandle.call(this, vertexCoordinates.length - 1, ringIndex));
1004+
}
1005+
1006+
} else {
1007+
const ringIndex = 0;
1008+
const vertexCoordinates = getVertexCoordinates(ringIndex);
1009+
for (let i = 0, len = vertexCoordinates.length; i < len; i++) {
1010+
vertexHandles[ringIndex].push(createVertexHandle.call(this, i, ringIndex));
1011+
if (i < len - 1) {
1012+
newVertexHandles[ringIndex].push(createNewVertexHandle.call(this, i, ringIndex));
1013+
}
1014+
}
9841015
}
9851016
this._addRefreshHook(() => {
986-
for (let i = newVertexHandles.length - 1; i >= 0; i--) {
987-
newVertexHandles[i][propertyOfVertexRefreshFn]();
1017+
for (const ringIndex in newVertexHandles) {
1018+
for (let i = newVertexHandles[ringIndex].length - 1; i >= 0; i--) {
1019+
newVertexHandles[ringIndex][i][propertyOfVertexRefreshFn](ringIndex);
1020+
}
9881021
}
989-
for (let i = vertexHandles.length - 1; i >= 0; i--) {
990-
vertexHandles[i][propertyOfVertexRefreshFn]();
1022+
for (const ringIndex in vertexHandles) {
1023+
for (let i = vertexHandles[ringIndex].length - 1; i >= 0; i--) {
1024+
vertexHandles[ringIndex][i][propertyOfVertexRefreshFn](ringIndex);
1025+
}
9911026
}
9921027
});
9931028
}

0 commit comments

Comments
 (0)