Example #1
0
    void GeoParser::parseGeoJSONPolygon(const BSONObj& obj, S2Polygon* out) {
        const vector<BSONElement>& coordinates =
            obj.getFieldDotted(GEOJSON_COORDINATES).Array();

        const vector<BSONElement>& exteriorRing = coordinates[0].Array();
        vector<S2Point> exteriorVertices;
        parsePoints(exteriorRing, &exteriorVertices);

        S2PolygonBuilderOptions polyOptions;
        polyOptions.set_validate(true);
        S2PolygonBuilder polyBuilder(polyOptions);
        S2Loop exteriorLoop(exteriorVertices);
        if (exteriorLoop.is_hole()) {
            exteriorLoop.Invert();
        }
        polyBuilder.AddLoop(&exteriorLoop);

        // Subsequent arrays of coordinates are interior rings/holes.
        for (size_t i = 1; i < coordinates.size(); ++i) {
            vector<S2Point> holePoints;
            parsePoints(coordinates[i].Array(), &holePoints);
            // Interior rings are clockwise.
            S2Loop holeLoop(holePoints);
            if (!holeLoop.is_hole()) {
                holeLoop.Invert();
            }
            polyBuilder.AddLoop(&holeLoop);
        }

        polyBuilder.AssemblePolygon(out, NULL);
    }
Example #2
0
    static bool parseGeoJSONPolygonCoordinates(const vector<BSONElement>& coordinates,
                                               const BSONObj &sourceObject,
                                               S2Polygon *out) {

        const vector<BSONElement>& exteriorRing = coordinates[0].Array();
        vector<S2Point> exteriorVertices;
        if (!parsePoints(exteriorRing, &exteriorVertices)) { return false; }
        eraseDuplicatePoints(&exteriorVertices);
        // The last point is duplicated.  We drop it, since S2Loop expects no
        // duplicate points
        exteriorVertices.resize(exteriorVertices.size() - 1);
        // S2 Polygon loops must have 3 vertices
        if (exteriorVertices.size() < 3) { return false; }

        S2PolygonBuilderOptions polyOptions;
        polyOptions.set_validate(true);
        // Don't silently eliminate duplicate edges.
        polyOptions.set_xor_edges(false);
        S2PolygonBuilder polyBuilder(polyOptions);
        S2Loop exteriorLoop(exteriorVertices);
        exteriorLoop.Normalize();
        if (exteriorLoop.is_hole()) {
            exteriorLoop.Invert();
        }
        if (!exteriorLoop.IsValid()) { return false; }
        polyBuilder.AddLoop(&exteriorLoop);

        // Subsequent arrays of coordinates are interior rings/holes.
        for (size_t i = 1; i < coordinates.size(); ++i) {
            vector<S2Point> holePoints;
            if (!parsePoints(coordinates[i].Array(), &holePoints)) { return false; }
            eraseDuplicatePoints(&holePoints);
            // Drop the duplicated last point.
            holePoints.resize(holePoints.size() - 1);
            // S2 Polygon loops must have 3 vertices
            if (holePoints.size() < 3) { return false; }
            // Interior rings are clockwise.
            S2Loop holeLoop(holePoints);
            holeLoop.Normalize();
            if (!holeLoop.IsValid()) { return false; }
            if (!holeLoop.is_hole()) {
                if (!exteriorLoop.Contains(&holeLoop)) { return false; }
                holeLoop.Invert();
            } else {
                // It's already clockwise; we need to invert once to check that it's contained in
                // the shell, then invert again.
                holeLoop.Invert();
                if (!exteriorLoop.Contains(&holeLoop)) { return false; }
                holeLoop.Invert();
            }
            polyBuilder.AddLoop(&holeLoop);
        }

        return polyBuilder.AssemblePolygon(out, NULL);
    }
Example #3
0
    void GeoParser::parseGeoJSONPolygon(const BSONObj& obj, S2Polygon* out) {
        const vector<BSONElement>& coordinates =
            obj.getFieldDotted(GEOJSON_COORDINATES).Array();

        const vector<BSONElement>& exteriorRing = coordinates[0].Array();
        vector<S2Point> exteriorVertices;
        parsePoints(exteriorRing, &exteriorVertices);
        // The last point is duplicated.  We drop it, since S2Loop expects no
        // duplicate points
        exteriorVertices.resize(exteriorVertices.size() - 1);

        S2PolygonBuilderOptions polyOptions;
        polyOptions.set_validate(true);
        // Don't silently eliminate duplicate edges.
        polyOptions.set_xor_edges(false);
        S2PolygonBuilder polyBuilder(polyOptions);
        S2Loop exteriorLoop(exteriorVertices);
        exteriorLoop.Normalize();
        if (exteriorLoop.is_hole()) {
            exteriorLoop.Invert();
        }
        uassert(16693, "Exterior shell of polygon is invalid: " + obj.toString(),
                exteriorLoop.IsValid());
        polyBuilder.AddLoop(&exteriorLoop);

        // Subsequent arrays of coordinates are interior rings/holes.
        for (size_t i = 1; i < coordinates.size(); ++i) {
            vector<S2Point> holePoints;
            parsePoints(coordinates[i].Array(), &holePoints);
            // Drop the duplicated last point.
            holePoints.resize(holePoints.size() - 1);
            // Interior rings are clockwise.
            S2Loop holeLoop(holePoints);
            holeLoop.Normalize();
            uassert(16694, "Interior hole of polygon is invalid: " + obj.toString(),
                    holeLoop.IsValid());
            if (!holeLoop.is_hole()) {
                holeLoop.Invert();
            }
            polyBuilder.AddLoop(&holeLoop);
        }

        uassert(16695, "Couldn't assemble polygon: " + obj.toString(),
                polyBuilder.AssemblePolygon(out, NULL));
    }
Example #4
0
    void GeoParser::parseLegacyPolygon(const BSONObj &obj, S2Polygon *out) {
        vector<S2Point> points;

        BSONObjIterator coordIt(obj);
        while (coordIt.more()) {
            BSONElement coord = coordIt.next();
            S2Point point;
            parseLegacyPoint(coord.Obj(), &point);
            points.push_back(point);
        }
        points.push_back(points[0]);

        S2PolygonBuilderOptions polyOptions;
        polyOptions.set_validate(true);
        S2PolygonBuilder polyBuilder(polyOptions);
        S2Loop exteriorLoop(points);
        if (exteriorLoop.is_hole()) {
            exteriorLoop.Invert();
        }
        polyBuilder.AddLoop(&exteriorLoop);
        polyBuilder.AssemblePolygon(out, NULL);
    }
Example #5
0
void
OverlayOp::computeOverlay(int opCode)
	//throw(TopologyException *)
{

	// copy points from input Geometries.
	// This ensures that any Point geometries
	// in the input are considered for inclusion in the result set

	copyPoints(0);
	copyPoints(1);


	// node the input Geometries
	delete (*arg)[0]->computeSelfNodes(li,false);
	delete (*arg)[1]->computeSelfNodes(li,false);

#if DEBUG
	cerr<<"OverlayOp::computeOverlay: computed SelfNodes"<<endl;
#endif

	// compute intersections between edges of the two input geometries
	delete (*arg)[0]->computeEdgeIntersections((*arg)[1],li,true);

#if DEBUG
	cerr<<"OverlayOp::computeOverlay: computed EdgeIntersections"<<endl;
	cerr<<"OverlayOp::computeOverlay: li: "<<li->toString()<<endl;
#endif


	vector<Edge*> baseSplitEdges;
	(*arg)[0]->computeSplitEdges(&baseSplitEdges);
	(*arg)[1]->computeSplitEdges(&baseSplitEdges);

	// add the noded edges to this result graph
	insertUniqueEdges(&baseSplitEdges);
	computeLabelsFromDepths();
	replaceCollapsedEdges();
	//Debug.println(edgeList);

    	// debugging only
    	//NodingValidator nv = new NodingValidator(edgeList.getEdges());
    	//nv.checkValid();

	graph->addEdges(edgeList->getEdges());

	// this can throw TopologyException *
	computeLabelling();

	//Debug.printWatch();
	labelIncompleteNodes();
	//Debug.printWatch();
	//nodeMap.print(System.out);


	/*
	 * The ordering of building the result Geometries is important.
	 * Areas must be built before lines, which must be built
	 * before points.
	 * This is so that lines which are covered by areas are not
	 * included explicitly, and similarly for points.
	 */
	findResultAreaEdges(opCode);
	cancelDuplicateResultEdges();

	PolygonBuilder polyBuilder(geomFact,cga);
	
	// might throw a TopologyException *
	polyBuilder.add(graph);

	vector<Geometry*> *gv=polyBuilder.getPolygons();
	size_t gvSize=gv->size();
	resultPolyList=new vector<Polygon*>(gvSize);
	for(size_t i=0; i<gvSize; ++i) {
		(*resultPolyList)[i]=(Polygon*)(*gv)[i];
	}
	delete gv;

	LineBuilder lineBuilder(this,geomFact,ptLocator);
	resultLineList=lineBuilder.build(opCode);

	PointBuilder pointBuilder(this,geomFact,ptLocator);
	resultPointList=pointBuilder.build(opCode);

	// gather the results from all calculations into a single
	// Geometry for the result set
	resultGeom=computeGeometry(resultPointList,resultLineList,resultPolyList);
#if USE_ELEVATION_MATRIX
	elevationMatrix->elevate(resultGeom);
#endif // USE_ELEVATION_MATRIX
	


}