Beispiel #1
0
Polygon*
GeometryEditor::editPolygon(const Polygon *polygon,GeometryEditorOperation *operation)
{
	Polygon* newPolygon=(Polygon*) operation->edit(polygon, factory);
	if (newPolygon->isEmpty()) {
		//RemoveSelectedPlugIn relies on this behaviour. [Jon Aquino]
		return newPolygon;
	}
	LinearRing* shell = (LinearRing*) edit(newPolygon->getExteriorRing(),operation);
	if (shell->isEmpty()) {
		//RemoveSelectedPlugIn relies on this behaviour. [Jon Aquino]
		delete shell;
		delete newPolygon;
		return factory->createPolygon(NULL,NULL);
	}

	vector<Geometry*> *holes=new vector<Geometry*>;
	for (int i=0;i<newPolygon->getNumInteriorRing(); i++) {
		LinearRing *hole =(LinearRing*) edit(newPolygon->getInteriorRingN(i),operation);
		if (hole->isEmpty()) {
			continue;
		}
		holes->push_back(hole);
	}
	delete newPolygon;
	return factory->createPolygon(shell,holes);
}
TEST(TileCover, DISABLED_FuzzPoly) {
    while(1)
    {
        std::srand (time(NULL));
        std::size_t len = std::rand() % 10000 + 3;
        Polygon<double> polygon;

        std::size_t num_rings = 1;
        num_rings += std::rand() % 5;
        while (num_rings > 0) {
            LinearRing<double> ring;
            for (std::size_t i = 0; i < len; ++i) {
                double x = std::rand() % 180;
                double y = std::rand() % 90;

                ring.push_back({x,y});
            }
            polygon.emplace_back(ring);
            --num_rings;
        }
        
        std::clog << ".";
        util::TileCover tc(polygon, 5);
        while(tc.next()) {
        };
    }
}
Beispiel #3
0
void
Polygon::apply_rw(const CoordinateFilter *filter)
{
	shell->apply_rw(filter);
	for(size_t i=0, n=holes->size(); i<n; ++i)
	{
		LinearRing* lr = dynamic_cast<LinearRing *>((*holes)[i]);
		lr->apply_rw(filter);
	}
}
Beispiel #4
0
/*public*/
EdgeRing*
EdgeRing::findEdgeRingContaining(EdgeRing* testEr,
                                 vector<EdgeRing*>* shellList)
{
    const LinearRing* testRing = testEr->getRingInternal();
    if(! testRing) {
        return nullptr;
    }
    const Envelope* testEnv = testRing->getEnvelopeInternal();
    Coordinate testPt = testRing->getCoordinateN(0);
    EdgeRing* minShell = nullptr;
    const Envelope* minEnv = nullptr;

    typedef std::vector<EdgeRing*> ERList;
    for(ERList::size_type i = 0, e = shellList->size(); i < e; ++i) {
        EdgeRing* tryShell = (*shellList)[i];
        LinearRing* tryRing = tryShell->getRingInternal();
        const Envelope* tryEnv = tryRing->getEnvelopeInternal();
        if(minShell != nullptr) {
            minEnv = minShell->getRingInternal()->getEnvelopeInternal();
        }
        bool isContained = false;

        // the hole envelope cannot equal the shell envelope

        if(tryEnv->equals(testEnv)) {
            continue;
        }

        const CoordinateSequence* tryCoords =
            tryRing->getCoordinatesRO();

        if(tryEnv->contains(testEnv)) {

            // TODO: don't copy testPt !
            testPt = ptNotInList(testRing->getCoordinatesRO(), tryCoords);

            if(PointLocation::isInRing(testPt, tryCoords)) {
                isContained = true;
            }

        }

        // check if this new containing ring is smaller
        // than the current minimum ring
        if(isContained) {
            if(minShell == nullptr || minEnv->contains(tryEnv)) {
                minShell = tryShell;
            }
        }
    }
    return minShell;
}
Beispiel #5
0
/*
 *  Returns the area of this <code>Polygon</code>
 *
 * @return the area of the polygon
 */
double
Polygon::getArea() const
{
	double area=0.0;
	area+=fabs(algorithm::CGAlgorithms::signedArea(shell->getCoordinatesRO()));
	for(size_t i=0, n=holes->size(); i<n; ++i)
	{
		LinearRing *lr = static_cast<LinearRing *>((*holes)[i]);
		const CoordinateSequence *h=lr->getCoordinatesRO();
        	area-=fabs(algorithm::CGAlgorithms::signedArea(h));
	}
	return area;
}
bool
QuadtreeNestedRingTester::isNonNested()
{
    buildQuadtree();
    for(size_t i = 0, ni = rings.size(); i < ni; ++i) {
        const LinearRing* innerRing = rings[i];
        const CoordinateSequence* innerRingPts = innerRing->getCoordinatesRO();
        const Envelope* envi = innerRing->getEnvelopeInternal();

        vector<void*> results;
        qt->query(envi, results);
        for(size_t j = 0, nj = results.size(); j < nj; ++j) {
            LinearRing* searchRing = (LinearRing*)results[j];
            const CoordinateSequence* searchRingPts = searchRing->getCoordinatesRO();

            if(innerRing == searchRing) {
                continue;
            }

            const Envelope* e1 = innerRing->getEnvelopeInternal();
            const Envelope* e2 = searchRing->getEnvelopeInternal();
            if(!e1->intersects(e2)) {
                continue;
            }

            const Coordinate* innerRingPt = IsValidOp::findPtNotNode(innerRingPts,
                                            searchRing, graph);

            // Unable to find a ring point not a node of the search ring
            assert(innerRingPt != nullptr);

            bool isInside = PointLocation::isInRing(*innerRingPt, searchRingPts);
            if(isInside) {
                /*
                 * innerRingPt is const just because the input
                 * CoordinateSequence is const. If the input
                 * Polygon survives lifetime of this object
                 * we are safe.
                 */
                nestedPt = const_cast<Coordinate*>(innerRingPt);
                return false;
            }
        }
    }
    return true;
}
        void updateNonClosedRing(LinearRing& ring)
	{
		CoordinateSequence& pts = *(const_cast<CoordinateSequence*>(
			ring.getCoordinatesRO()
					    ));
		Coordinate c = pts[0];
		c.x += 0.0001;
		pts.setAt(c, 0);
	}
Beispiel #8
0
Polygon*
GeometryEditor::editPolygon(const Polygon *polygon,GeometryEditorOperation *operation)
{
	Polygon* newPolygon= dynamic_cast<Polygon*>(
    operation->edit(polygon, factory)
  );
	if (newPolygon->isEmpty()) {
		//RemoveSelectedPlugIn relies on this behaviour. [Jon Aquino]
		return newPolygon;
	}

	Geometry* editResult = edit(newPolygon->getExteriorRing(),operation);

	LinearRing* shell = dynamic_cast<LinearRing*>(editResult);
	if (shell->isEmpty()) {
		//RemoveSelectedPlugIn relies on this behaviour. [Jon Aquino]
		delete shell;
		delete newPolygon;
		return factory->createPolygon(NULL,NULL);
	}

	vector<Geometry*> *holes=new vector<Geometry*>;
	for (size_t i=0, n=newPolygon->getNumInteriorRing(); i<n; ++i)
	{

		Geometry *hole_geom = edit(newPolygon->getInteriorRingN(i),
			operation);

		LinearRing *hole = dynamic_cast<LinearRing*>(hole_geom);
		assert(hole);

		if (hole->isEmpty())
		{
			continue;
		}
		holes->push_back(hole);
	}
	delete newPolygon;
	return factory->createPolygon(shell,holes);
}
Beispiel #9
0
void Polygon::AddGeometry(Geometry *pGeometry)
{
	LinearRing *pring = dynamic_cast<LinearRing*>(pGeometry);
	
	if(pring ==NULL)
	{
		return;
	}
	//如果环是不闭合的,并且不是一个空环,则不能加入到多边形中
	if(!pring->isClosed() && !pring->isEmpty())
	{
		return;
	}
	//当外环为空时,将这个环替换外环
	if(shell->isEmpty())
	{
        delete shell;
		shell =pring;
		return;
	}

	holes->push_back(pring);
}
 bool TextureCoordinates::targets(const LinearRing& ring) const
 {
     return m_targetID == ring.getId();
 }
static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) {
    const double size = util::EXTENT * std::pow(2, tileID.z);
    const double x0 = util::EXTENT * tileID.x;
    const double y0 = util::EXTENT * tileID.y;

    auto tileCoordinatesToLatLng = [&] (const Point<int16_t>& p) {
        double y2 = 180 - (p.y + y0) * 360 / size;
        return Point<double>(
            (p.x + x0) * 360 / size - 180,
            360.0 / M_PI * std::atan(std::exp(y2 * M_PI / 180)) - 90.0
        );
    };

    GeometryCollection geometries = geometryTileFeature.getGeometries();

    switch (geometryTileFeature.getType()) {
        case FeatureType::Unknown: {
            assert(false);
            return Point<double>(NAN, NAN);
        }

        case FeatureType::Point: {
            MultiPoint<double> multiPoint;
            for (const auto& p : geometries.at(0)) {
                multiPoint.push_back(tileCoordinatesToLatLng(p));
            }
            if (multiPoint.size() == 1) {
                return multiPoint[0];
            } else {
                return multiPoint;
            }
        }

        case FeatureType::LineString: {
            MultiLineString<double> multiLineString;
            for (const auto& g : geometries) {
                LineString<double> lineString;
                for (const auto& p : g) {
                    lineString.push_back(tileCoordinatesToLatLng(p));
                }
                multiLineString.push_back(std::move(lineString));
            }
            if (multiLineString.size() == 1) {
                return multiLineString[0];
            } else {
                return multiLineString;
            }
        }

        case FeatureType::Polygon: {
            MultiPolygon<double> multiPolygon;
            for (const auto& pg : classifyRings(geometries)) {
                Polygon<double> polygon;
                for (const auto& r : pg) {
                    LinearRing<double> linearRing;
                    for (const auto& p : r) {
                        linearRing.push_back(tileCoordinatesToLatLng(p));
                    }
                    polygon.push_back(std::move(linearRing));
                }
                multiPolygon.push_back(std::move(polygon));
            }
            if (multiPolygon.size() == 1) {
                return multiPolygon[0];
            } else {
                return multiPolygon;
            }
        }
    }

    // Unreachable, but placate GCC.
    return Point<double>();
}