Enhances the default {@link SpatialContext} with support for Polygons (and other geometry) plus reading WKT. The popular JTS library does the heavy lifting.
Наследование: SpatialContext
Пример #1
0
		public SpatialField(string fieldName, SpatialOptions options)
		{
			this.options = options;
			ntsContext = CreateNtsContext(options);
			shapeStringReadWriter = new ShapeStringReadWriter(options, ntsContext);
			strategy = CreateStrategy(fieldName, options, ntsContext);
		}
Пример #2
0
		static SpatialIndex()
		{
			Context = new NtsSpatialContext(true);
			GeometryServiceProvider.Instance = new NtsGeometryServices();

			shapeReadWriter = new NtsShapeReadWriter(Context);
		}
Пример #3
0
		static SpatialIndex()
		{
			Context = NtsSpatialContext.GEO_KM;
			GeometryServiceProvider.Instance = new NtsGeometryServices();

			ShapeReadWriter = new NtsShapeReadWriter(Context);
		}
Пример #4
0
 public static double GetGeographicalDistance(double fromLat, double fromLng, double toLat, double toLng)
 {
     var Context = new NtsSpatialContext(true);
     Point ptFrom = Context.MakePoint(fromLng, fromLat);
     Point ptTo = Context.MakePoint(toLng, toLat);
     var distance = Context.GetDistCalc().Distance(ptFrom, ptTo);
     return (distance / RadiansToDegrees) * EarthMeanRadiusKm;
 }
Пример #5
0
        public NtsGeometry(IGeometry geom, NtsSpatialContext ctx, bool dateline180Check)
        {
            this.ctx = ctx;

            //GeometryCollection isn't supported in relate()
            if (geom.GetType() == typeof(GeometryCollection))
                throw new ArgumentException("NtsGeometry does not support GeometryCollection but does support its subclasses.");

            //NOTE: All this logic is fairly expensive. There are some short-circuit checks though.
            if (ctx.IsGeo())
            {
                //Unwraps the geometry across the dateline so it exceeds the standard geo bounds (-180 to +180).
                if (dateline180Check)
                    UnwrapDateline(geom); //potentially modifies geom
                //If given multiple overlapping polygons, fix it by union
                geom = UnionGeometryCollection(geom); //returns same or new geom
                Envelope unwrappedEnv = geom.EnvelopeInternal;

                //Cuts an unwrapped geometry back into overlaid pages in the standard geo bounds.
                geom = CutUnwrappedGeomInto360(geom); //returns same or new geom
                Debug.Assert(geom.EnvelopeInternal.Width <= 360);
                Debug.Assert(geom.GetType() != typeof (GeometryCollection)); //double check

                //note: this bbox may be sub-optimal. If geom is a collection of things near the dateline on both sides then
                // the bbox will needlessly span most or all of the globe longitudinally.
                // TODO so consider using MultiShape's planned minimal geo bounding box algorithm once implemented.
                double envWidth = unwrappedEnv.Width;

                //adjust minX and maxX considering the dateline and world wrap
                double minX, maxX;
                if (envWidth >= 360)
                {
                    minX = -180;
                    maxX = 180;
                }
                else
                {
                    minX = unwrappedEnv.MinX;
                    maxX = DistanceUtils.NormLonDEG(unwrappedEnv.MinX + envWidth);
                }
                bbox = new RectangleImpl(minX, maxX, unwrappedEnv.MinY, unwrappedEnv.MaxY, ctx);
            }
            else
            {//not geo
                Envelope env = geom.EnvelopeInternal;
                bbox = new RectangleImpl(env.MinX, env.MaxX, env.MinY, env.MaxY, ctx);
            }
            var _ = geom.EnvelopeInternal;//ensure envelope is cached internally, which is lazy evaluated. Keeps this thread-safe.

            //Check geom validity; use helpful error
            // TODO add way to conditionally skip at your peril later
            var isValidOp = new IsValidOp(geom);
            if (!isValidOp.IsValid)
                throw new InvalidShapeException(isValidOp.ValidationError.ToString());
            this.geom = geom;

            this._hasArea = !((geom is ILineal) || (geom is IPuntal));
        }
Пример #6
0
		private NtsSpatialContext CreateNtsContext(SpatialOptions opt)
		{
			if (opt.Type == SpatialFieldType.Cartesian)
			{
				var nts = new NtsSpatialContext(new GeometryFactory(), false, new CartesianDistCalc(), null);
				nts.GetWorldBounds().Reset(opt.MinX, opt.MaxX, opt.MinY, opt.MaxY);
				return nts;
			}
			return GeoContext;
		}
Пример #7
0
        private static readonly double LUCENE_4464_distErrPct = SpatialArgs.DEFAULT_DISTERRPCT;//DEFAULT 2.5%

        public NtsPolygonTest()
        {
            //var args = new HashMap<String, String> {{"spatialContextFactory", "com.spatial4j.core.context.jts.JtsSpatialContextFactory"}};
            //SpatialContextFactory.MakeSpatialContext(args, getClass().getClassLoader());
            ctx = new NtsSpatialContext(true);

            var grid = new GeohashPrefixTree(ctx, 11);//< 1 meter == 11 maxLevels
            this.strategy = new RecursivePrefixTreeStrategy(grid, GetType().Name);
            ((RecursivePrefixTreeStrategy)this.strategy).DistErrPct = LUCENE_4464_distErrPct;//1% radius (small!)
        }
Пример #8
0
		private SpatialStrategy CreateStrategy(string fieldName, SpatialOptions opt, NtsSpatialContext context)
		{
			switch (opt.Strategy)
			{
				case SpatialSearchStrategy.GeohashPrefixTree:
					return new RecursivePrefixTreeStrategyThatSupportsWithin(new GeohashPrefixTree(context, opt.MaxTreeLevel), fieldName);
				case SpatialSearchStrategy.QuadPrefixTree:
					return new RecursivePrefixTreeStrategyThatSupportsWithin(new QuadPrefixTree(context, opt.MaxTreeLevel), fieldName);
				case SpatialSearchStrategy.BoundingBox:
					return new BBoxStrategyThatSupportsAllShapes(context, fieldName);
			}
			return null;
		}
Пример #9
0
        static NtsSpatialContext()
        {
            // spatial4n specific - need to bootstrap GeoAPI with
            // the NetTopologySuite geometry. See:
            // https://github.com/NetTopologySuite/NetTopologySuite/issues/189#issuecomment-324844404
#if NETSTANDARD
            GeoAPI.NetTopologySuiteBootstrapper.Bootstrap();
#endif

            NtsSpatialContextFactory factory = new NtsSpatialContextFactory();
            factory.geo = true;
            GEO         = new NtsSpatialContext(factory);
        }
Пример #10
0
 public NtsShapeReadWriter(NtsSpatialContext ctx, bool normalizeGeomCoords)
     : base(ctx)
 {
     this.normalizeGeomCoords = normalizeGeomCoords;
 }
Пример #11
0
 private NtsShapeReadWriter CreateNtsShapeReadWriter(SpatialOptions opt, NtsSpatialContext ntsContext)
 {
     if (opt.Type == SpatialFieldType.Cartesian)
         return new NtsShapeReadWriter(ntsContext, false);
     return geoShapeReadWriter ?? (geoShapeReadWriter = new NtsShapeReadWriter(ntsContext, false));
 }
Пример #12
0
 public ShapeStringReadWriter(SpatialOptions options, NtsSpatialContext context)
 {
     this.options = options;
     this.ntsShapeReadWriter = CreateNtsShapeReadWriter(options, context);
     this.shapeStringConverter = new ShapeStringConverter(options);
 }
Пример #13
0
		static SpatialField()
		{
			GeometryServiceProvider.Instance = new NtsGeometryServices();
			GeoContext = new NtsSpatialContext(true);
			ShapeConverter = new ShapeConverter();
		}
Пример #14
0
        private bool normalizeGeomCoords = true; //TODO make configurable

        #endregion Fields

        #region Constructors

        public NtsShapeReadWriter(NtsSpatialContext ctx)
            : base(ctx)
        {
        }
Пример #15
0
 public ShapeReaderWriterCoordinateSequenceFilter(NtsSpatialContext ctx, bool normalizeGeomCoords)
 {
     _ctx = ctx;
     _normalizeGeomCoords = normalizeGeomCoords;
 }
Пример #16
0
 public NtsPolygonTestCoordinateFilter(NtsSpatialContext ctx)
 {
     _ctx = ctx;
 }
Пример #17
0
 public ShapeReaderWriterCoordinateSequenceFilter(NtsSpatialContext ctx)
 {
     _ctx = ctx;
 }