[postgis-tickets] r16042 - Avoid an unneeded query for each added edge in TopoGeo_addLinestring
Sandro Santilli
strk at kbt.io
Sun Oct 22 09:34:02 PDT 2017
Author: strk
Date: 2017-10-22 09:34:02 -0700 (Sun, 22 Oct 2017)
New Revision: 16042
Modified:
trunk/liblwgeom/lwgeom_topo.c
Log:
Avoid an unneeded query for each added edge in TopoGeo_addLinestring
When endpoints are known not to move, don't query DB to check
the new position.
Modified: trunk/liblwgeom/lwgeom_topo.c
===================================================================
--- trunk/liblwgeom/lwgeom_topo.c 2017-10-22 16:29:04 UTC (rev 16041)
+++ trunk/liblwgeom/lwgeom_topo.c 2017-10-22 16:34:02 UTC (rev 16042)
@@ -5064,9 +5064,12 @@
* @param findFace if non-zero the code will determine which face
* contains the given point (unless it is known to be NOT
* isolated)
+ * @param moved if not-null will be set to 0 if the point was added
+ * w/out any snapping or 1 otherwise.
*/
static LWT_ELEMID
-_lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol, int findFace)
+_lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol, int
+ findFace, int *moved)
{
int num, i;
double mindist = FLT_MAX;
@@ -5137,6 +5140,7 @@
{
/* found an existing node */
if ( nodes ) _lwt_release_nodes(nodes, num);
+ if ( moved ) *moved = mindist == 0 ? 0 : 1;
return id;
}
}
@@ -5204,6 +5208,7 @@
/* project point to line, split edge by point */
prj = lwgeom_closest_point(g, pt);
+ if ( moved ) *moved = lwgeom_same(prj,pt) ? 0 : 1;
if ( lwgeom_has_z(pt) )
{{
/*
@@ -5388,6 +5393,7 @@
/* The point is isolated, add it as such */
/* TODO: pass 1 as last argument (skipChecks) ? */
id = _lwt_AddIsoNode(topo, -1, point, 0, findFace);
+ if ( moved ) *moved = 0;
if ( -1 == id )
{
/* should have invoked lwerror already, leaking memory */
@@ -5402,7 +5408,7 @@
LWT_ELEMID
lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol)
{
- return _lwt_AddPoint(topo, point, tol, 1);
+ return _lwt_AddPoint(topo, point, tol, 1, NULL);
}
/* Return identifier of an equal edge, 0 if none or -1 on error
@@ -5488,12 +5494,13 @@
{
LWCOLLECTION *col;
LWPOINT *start_point, *end_point;
- LWGEOM *tmp, *tmp2;
+ LWGEOM *tmp = 0, *tmp2;
LWT_ISO_NODE *node;
LWT_ELEMID nid[2]; /* start_node, end_node */
LWT_ELEMID id; /* edge id */
POINT4D p4d;
int nn, i;
+ int moved=0, mm;
LWDEBUGG(1, lwline_as_lwgeom(edge), "_lwtAddLineEdge");
LWDEBUGF(1, "_lwtAddLineEdge with tolerance %g", tol);
@@ -5506,10 +5513,12 @@
}
nid[0] = _lwt_AddPoint( topo, start_point,
_lwt_minTolerance(lwpoint_as_lwgeom(start_point)),
- handleFaceSplit );
+ handleFaceSplit, &mm );
lwpoint_free(start_point); /* too late if lwt_AddPoint calls lwerror */
if ( nid[0] == -1 ) return -1; /* lwerror should have been called */
+ moved += mm;
+
end_point = lwline_get_lwpoint(edge, edge->points->npoints-1);
if ( ! end_point )
{
@@ -5519,7 +5528,8 @@
}
nid[1] = _lwt_AddPoint( topo, end_point,
_lwt_minTolerance(lwpoint_as_lwgeom(end_point)),
- handleFaceSplit );
+ handleFaceSplit, &mm );
+ moved += mm;
lwpoint_free(end_point); /* too late if lwt_AddPoint calls lwerror */
if ( nid[1] == -1 ) return -1; /* lwerror should have been called */
@@ -5527,79 +5537,82 @@
-- Added endpoints may have drifted due to tolerance, so
-- we need to re-snap the edge to the new nodes before adding it
*/
-
- nn = nid[0] == nid[1] ? 1 : 2;
- node = lwt_be_getNodeById( topo, nid, &nn,
- LWT_COL_NODE_NODE_ID|LWT_COL_NODE_GEOM );
- if ( nn == -1 )
+ if ( moved )
{
- lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
- return -1;
- }
- start_point = NULL; end_point = NULL;
- for (i=0; i<nn; ++i)
- {
- if ( node[i].node_id == nid[0] ) start_point = node[i].geom;
- if ( node[i].node_id == nid[1] ) end_point = node[i].geom;
- }
- if ( ! start_point || ! end_point )
- {
- if ( nn ) _lwt_release_nodes(node, nn);
- lwerror("Could not find just-added nodes % " LWTFMT_ELEMID
- " and %" LWTFMT_ELEMID, nid[0], nid[1]);
- return -1;
- }
- /* snap */
+ nn = nid[0] == nid[1] ? 1 : 2;
+ node = lwt_be_getNodeById( topo, nid, &nn,
+ LWT_COL_NODE_NODE_ID|LWT_COL_NODE_GEOM );
+ if ( nn == -1 )
+ {
+ lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
+ return -1;
+ }
+ start_point = NULL; end_point = NULL;
+ for (i=0; i<nn; ++i)
+ {
+ if ( node[i].node_id == nid[0] ) start_point = node[i].geom;
+ if ( node[i].node_id == nid[1] ) end_point = node[i].geom;
+ }
+ if ( ! start_point || ! end_point )
+ {
+ if ( nn ) _lwt_release_nodes(node, nn);
+ lwerror("Could not find just-added nodes % " LWTFMT_ELEMID
+ " and %" LWTFMT_ELEMID, nid[0], nid[1]);
+ return -1;
+ }
- getPoint4d_p( start_point->point, 0, &p4d );
- lwline_setPoint4d(edge, 0, &p4d);
+ /* snap */
- getPoint4d_p( end_point->point, 0, &p4d );
- lwline_setPoint4d(edge, edge->points->npoints-1, &p4d);
+ getPoint4d_p( start_point->point, 0, &p4d );
+ lwline_setPoint4d(edge, 0, &p4d);
- if ( nn ) _lwt_release_nodes(node, nn);
+ getPoint4d_p( end_point->point, 0, &p4d );
+ lwline_setPoint4d(edge, edge->points->npoints-1, &p4d);
- /* make valid, after snap (to handle collapses) */
- tmp = lwgeom_make_valid(lwline_as_lwgeom(edge));
+ if ( nn ) _lwt_release_nodes(node, nn);
- col = lwgeom_as_lwcollection(tmp);
- if ( col )
- {{
+ /* make valid, after snap (to handle collapses) */
+ tmp = lwgeom_make_valid(lwline_as_lwgeom(edge));
- col = lwcollection_extract(col, LINETYPE);
+ col = lwgeom_as_lwcollection(tmp);
+ if ( col )
+ {{
- /* Check if the so-snapped edge collapsed (see #1650) */
- if ( col->ngeoms == 0 )
- {
+ col = lwcollection_extract(col, LINETYPE);
+
+ /* Check if the so-snapped edge collapsed (see #1650) */
+ if ( col->ngeoms == 0 )
+ {
+ lwcollection_free(col);
+ lwgeom_free(tmp);
+ LWDEBUG(1, "Made-valid snapped edge collapsed");
+ return 0;
+ }
+
+ tmp2 = lwgeom_clone_deep( col->geoms[0] );
+ lwgeom_free(tmp);
+ tmp = tmp2;
+ edge = lwgeom_as_lwline(tmp);
lwcollection_free(col);
- lwgeom_free(tmp);
- LWDEBUG(1, "Made-valid snapped edge collapsed");
- return 0;
- }
-
- tmp2 = lwgeom_clone_deep( col->geoms[0] );
- lwgeom_free(tmp);
- tmp = tmp2;
- edge = lwgeom_as_lwline(tmp);
- lwcollection_free(col);
- if ( ! edge )
+ if ( ! edge )
+ {
+ /* should never happen */
+ lwerror("lwcollection_extract(LINETYPE) returned a non-line?");
+ return -1;
+ }
+ }}
+ else
{
- /* should never happen */
- lwerror("lwcollection_extract(LINETYPE) returned a non-line?");
- return -1;
+ edge = lwgeom_as_lwline(tmp);
+ if ( ! edge )
+ {
+ LWDEBUGF(1, "Made-valid snapped edge collapsed to %s",
+ lwtype_name(lwgeom_get_type(tmp)));
+ lwgeom_free(tmp);
+ return 0;
+ }
}
- }}
- else
- {
- edge = lwgeom_as_lwline(tmp);
- if ( ! edge )
- {
- LWDEBUGF(1, "Made-valid snapped edge collapsed to %s",
- lwtype_name(lwgeom_get_type(tmp)));
- lwgeom_free(tmp);
- return 0;
- }
}
/* check if the so-snapped edge _now_ exists */
@@ -5607,12 +5620,12 @@
LWDEBUGF(1, "_lwt_GetEqualEdge returned %" LWTFMT_ELEMID, id);
if ( id == -1 )
{
- lwgeom_free(tmp); /* probably too late, due to internal lwerror */
+ if ( tmp ) lwgeom_free(tmp); /* probably too late, due to internal lwerror */
return -1;
}
if ( id )
{
- lwgeom_free(tmp); /* possibly takes "edge" down with it */
+ if ( tmp ) lwgeom_free(tmp); /* possibly takes "edge" down with it */
return id;
}
@@ -5625,7 +5638,7 @@
tmp2 = lwline_remove_repeated_points(edge, tol);
LWDEBUGG(1, tmp2, "Repeated-point removed");
edge = lwgeom_as_lwline(tmp2);
- lwgeom_free(tmp);
+ if ( tmp ) lwgeom_free(tmp);
tmp = tmp2;
/* check if the so-decimated edge _now_ exists */
More information about the postgis-tickets
mailing list