Giter VIP home page Giter VIP logo

geoapi's Introduction

NetTopologySuite

Gitter

A .NET GIS solution that is fast and reliable for the .NET platform. NetTopologySuite is a direct-port of all the functionalities offered by JTS Topology Suite: NTS expose JTS in a '.NET way', as example using Properties, Indexers etc...

An excerpt from JTS website explains the capabilities of NTS too: "The JTS Topology Suite is an API for modelling and manipulating 2-dimensional linear geometry. It provides numerous geometric predicates and functions. JTS conforms to the Simple Features Specification for SQL published by the Open GIS Consortium."

Enjoy using them!

Documentation

A documentation of the NetTopologySuite API based on code xml comments is accessible on github-pages.
To get you started, we have set up an introductory Getting Started page. A list of known issues is available, too.

Upgrading to 2.x from 1.x

A wiki page has been started to try to document the breaking changes in 2.0 when coming from 1.x.

Install with NuGet package manager

Stable NuGet Status Build Status

Stable releases are hosted on the default NuGet feed. You can install them using the following command on the package manager command line

PM> Install-Package NetTopologySuite

Pre release MyGet PreRelease Status Build Status

Pre-Release versions of NetTopologySuite are hosted on MyGet. The sources for the NetTopologySuite feed are as follows:

Version URL
NuGet v3 https://www.myget.org/F/nettopologysuite/api/v3/index.json
NuGet v2 https://www.myget.org/F/nettopologysuite/api/v2

You can install the latest pre-release package using the following command on the package manager command line

PM> Install-Package NetTopologySuite -pre -source "<Nuget v3 or NuGet v2 source>"

geoapi's People

Contributors

airbreather avatar dguidi avatar fobermaier avatar xivk avatar yohdeadfall avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geoapi's Issues

GeoAPI.CoordinateSystems nuget package

I split up the GeoAPI package into GeoAPI and GeoAPI.CoordinateSystems.

We need to

  • rename GeoAPI to GeoAPI.Core package,
  • add GeoAPI.CoordinateSystems package and
  • add GeoAPI meta package

As @xivk maintains the build server pushing the packages, could you please help doing that?

Support for the M ordinates

Is the support for the M ordinates is planned or I don't understand how it works

The coordinate.cs is the central class for a coordinate but what about having custom class like:

CoordinateXY
CoordinateXYZ
CoordinateXYM
CoordinateXYZM

Building against NetCore 2.0 (netcoreapp2.0) on Linux

Hi,
I managed, with some effort, to build GeoAPI for the netcoreapp2.0 target. I had to disable SignAssembly and remove Consts.Product from the AssemblyInfo. Unit tests passed. If you like I can create a pull request.
Cheers!

support .NET core 3.0

We recently upgraded to dotnet core 3.0. We need GeoAPI in our api. We actually need this feature as fast as possible, to deploy in production.

What's needed :

  • Make the GeoAPI compatible with .net core 3.0

Please answer me when i'ts done.
Thanks

.NET Core Nuget package

Hello.

There is already a working .NET Core project for GeoAPI. Are there any chances of releasing a nuget package?

List of points -> polygon

does GeoAPI provide some sort of function to create a polygon that contains all points in a list? goal is the smallest polygon that contains all points. something like ST_MakePolygon or ST_ConvexHull known from PostgreSQL.

if there is no single function, is there a way to get to the polygon in steps?

thankful for help...

Future of Coordinate class

The former Coordinate class has been disected into four hierarchical classes:

  • CoordinateXY
    • CoordinateXYM
    • CoordinateXYZ
      • CoordinateXYZM

Where applicable, the defined interfaces have been refactored to use CoordinateXY as coordinate class.
Coordinate class has received some conversion operators (implicit vice versa to CoordinateXY and explicit to CoordinateXYZ)

We have two choices:

  • Mark Coordinate obsolete and let it stay around with CoordinateXY et. al. (πŸ‘ )
    • Might help transforming dependant projects
    • to be continued
  • Remove Coordinate, strip "XY" off of CoordinateXY et. at. (πŸ‘Ž )
    • Cleaner, less changes in NTS
    • to be continued

Serialization BUG

I've got an application where i serilaize a struct with an array of Coordinates. Here is a simple example.

[Serializable]
public struct CoordStruct
{
    public Coordinate[] Coordinates;

    public CoordStruct(Coordinate[] coordinates)
    {
        Coordinates = coordinates;
    }
}

[Test]
public void TestSerialize()
{
    var coordStruct = new CoordStruct(new Coordinate[] { new Coordinate(1.0, 2.0, 3.0), new Coordinate(4.0, 5.0, 6.0) });
    var serializer = new System.Xml.Serialization.XmlSerializer(typeof(CoordStruct));
    var writer = new System.IO.StreamWriter(@"C:\Temp\Test.xml", false);
    serializer.Serialize(writer, coordStruct);
    writer.Close();
}

If i run this i get stuck in an infinite loop with a output like below.

<?xml version="1.0" encoding="utf-8"?>
<CoordStruct xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Coordinates>
    <Coordinate>
      <X>1</X>
      <Y>2</Y>
      <Z>3</Z>
      <CoordinateValue>
        <X>1</X>
        <Y>2</Y>
        <Z>3</Z>
        <CoordinateValue>
          <X>1</X>
          <Y>2</Y>
          <Z>3</Z>
          <CoordinateValue>
            <X>1</X>
            <Y>2</Y>
            <Z>3</Z>
            <CoordinateValue>
              <X>1</X>
              <Y>2</Y>
              <Z>3</Z>

I have tested to change Coordinate.cs

Line 134

/// <summary>
/// Gets/Sets <other>Coordinate</other>s (x,y,z) values.
/// </summary>
[System.Xml.Serialization.XmlIgnore]
public Coordinate CoordinateValue
{
    get { return this; }
    set
    {
        X = value.X;
        Y = value.Y;
        Z = value.Z;
    }
}

Then i get this XML

<?xml version="1.0" encoding="utf-8"?>
<CoordStruct xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Coordinates>
    <Coordinate>
      <X>1</X>
      <Y>2</Y>
      <Z>3</Z>
    </Coordinate>
    <Coordinate>
      <X>4</X>
      <Y>5</Y>
      <Z>6</Z>
    </Coordinate>
  </Coordinates>
</CoordStruct>

The problem is that System.Xml.Serialization assembly is only available from v4.5 so it wont build with the rest of the frameworks.
I can create a pull request but i need som help how to approach this.

Is the GeoAPI 1.7.5 Nuget package missing dll's?

When I update my solution to GeoAPI 1.7.5, my build breaks with dozens of missing references to GeoAPI.Geometries.
When I check the packages\GeoAPI.1.7.5 folder, all that is there is GeoAPI.1.7.5.nupkg.
Shouldn't there be a lib folder?

Update ICoordinateSystemServices interface

@becio has worked on an implementation for ICoordinateSystemServices interface, and it has proven to be not usable. His suggestion is this:

Here is a usable version:

/// <summary>
/// An interface for classes that can query coordinate system id's and and initialization strings
/// </summary>
public interface ICoordinateSystemServices
    {
        /// <summary>
        /// Gets the initialization string for the coordinate system defined by <paramref name="srid"/>.
        /// </summary>
        /// <param name="srid">The spatial reference id</param>
        /// <returns>The initialization string</returns>
        string GetCoordinateSystemInitializationString(int srid);

        /// <summary>
        /// Method to get the identifier, by which this coordinate system can be accessed.
        /// </summary>
        /// <param name="authority">The authority name</param>
        /// <param name="authorityCode">The code assigned by <paramref name="authority"/></param>
        /// <returns>The identifier or <value>null</value></returns>
        int? GetSRID(string authority, long authorityCode);
    }

Remove GeometryServiceProvider.Instance

This is somewhat related to #30, but that issue is very broad, so I wanted to give this its own arena for discussion.

GeometryServiceProvider.Instance isn't actually used anywhere in GeoAPI itself. Its sole purpose seems to be a common point of reference for downstream consumers.

This sounds neat, but it creates some problems:

  1. Downstream consumers need to set it themselves somehow, either by explicitly calling this sometime after being loaded (see NetTopologySuite/NetTopologySuite#236) or by passing this responsibility to their own consumers.
    • This creates its own friction, since it's not clear to ORM providers whether or not they should be setting this themselves.
  2. GeoAPI implementers shouldn't rely too much on this, even if they set it themselves, because some other GeoAPI implementer might set it later.
  3. Related challenges that have been overcome in the past year or two (from when this issue was opened).

In the face of all those problems, the practical benefits are questionable. I may have to eat my words on this, but in its current state, I find it difficult to imagine a particularly useful project that depends on GeoAPI.Core without also depending on something more concrete, such as NetTopologySuite.Core. So if there is, in fact, a need for a global default instance, then it could just as easily be NtsGeometryServices.Instance or something similar.

In a post-#30 world, there may be a use for having GeoAPI export a global variable that can be used as a default to reduce the friction of the API, depending on how the architecture looks in the end, but right now I feel that it doesn't add enough value on top of NtsGeometryServices.Instance to be worth keeping around (for reasons other than backwards-compatibility).

GetLoadableTypes should not throw exceptions

Method GeometryServiceProvider.GetLoadableTypes can crash with exceptions distinct from the 3 types currently accounted for (I had at least 2 distinct uncaught exceptions with a complex bin directory).
There should be a general untyped exception catch, on top of the 3 typed catches, to account for such unplanned conditions, since that method should not really ever crash.

Remove obsolete interfaces, classes and members

The following interfaces, classes, enums or some of their members have been marked obsolete (for a long time)

Item Reason
ICoordinate Its use was a big performance hit.
IEnvelope dito
GeoAPI.Operation.Buffer.BufferStyle has been superceeded by GeoAPI.Operation.Buffer.IBufferParameters
ICoordinateSequence.Reversed() not convorm with JTS
usage of System.ICloneable deprecated in JTS v1.15
Envelope.Overlaps usage of Envelope.Intersects preferred
IGeometryFactory.CreateMultiPoint(Coordinate[]); deprecated in JTS v1.15, use new CreateMultiPointFromCoords method
IGeometry.Equals usage of either IGeometry.EqualsExcact or IGeometry.EqualsTopologically preferred
IMultiLineString.Reversed() IGeometry.Reversed()

As we are having breaking changes for the v2.0 it might be the time to remove tem altogether.
Please use πŸ‘ or πŸ‘Ž on this post, comments are welcome, too.

Remove obsolete classes

There are a few classes that I needed to implement and are now throwing warnings due to obsolete attribute.
Can these classes be removed if they are obsolete?
I'm talking especially about ICoordinate and ICoordinate Transform(ICoordinate coordinate) in IMathTransform.
Might be related to #30.

Remove (standalone) GeoAPI

After #68 (comment) I've been thinking hard about this, and the more I do, the more confident I feel in saying that standalone GeoAPI feels like a solution in search of a problem.

As I mentioned in that linked comment, maintaining GeoAPI as a standalone thing means maintaining a separate Git repository, complete with its own separate GitHub issue tracker and its own separate milestones, containing a separate Visual Studio solution that builds two separate NuGet packages exposing types in their own separate namespaces.

This is a lot of separate stuff we have to maintain, and users probably see it as an arbitrary division (frankly, I do too, every time I have to add more using statements). We also often have to update both together anyway when porting new JTS updates, which adds a bit of a burden from time to time. There does not seem to be enough value here to justify all this cost, and I have not yet seen a proposal which would add the value that I claim is missing.

Even if we do something like the IGeometryDefinition idea from #68 (comment), that bundle of interfaces seems equally fit in the NetTopologySuite.Core package, especially since moving the mathematically interesting capabilities off of the GeoAPI interfaces only seems to decrease the already low number of use cases that could be satisfied with a reference to the GeoAPI.Core package without also referencing the NetTopologySuite.Core package.

So I propose that we put this GitHub project in maintenance mode (keeping it on 1.x), move the useful types it exposes into other projects in the NetTopologySuite organization starting with version 2.x, and continue ongoing efforts to redesign the API over there.

It's very tempting to try to do some of that redesign as part of this, but I think this issue needs to be focused on just moving what we already have (warts and all), only adjusting namespaces at most.

I volunteer to write up the specific details of where everything should go, once there's a consensus on whether or not to do this at all, but for the most part (I'm sure there would be exceptions):

  • Things that go into the GeoAPI.Core package would go somewhere under this folder, which becomes the NetTopologySuite.Core package.
  • Things that go into the GeoAPI.CoordinateSystems package would go under this folder, which becomes the NetTopologySuite.CoordinateSystems package.

If we do this, it's important that we keep the ability to trace the history of the moved files... probably, the commit on the "moved-to" side should include "as of NetTopologySuite/GeoAPI@d2b5ecb" (or whatever commit) when it adds the files so that we can click that link to go back to the history of the file on this side.

[question] Typescript definition for geoapi

Using NSwag to generate typescript api client for angular application

question is there any javascript library with typescript definition that contains some standard functionality like (calculating distance between points , intersection ..)

Add a LICENSE file

It looks like your intent was to license this with LGPL. However, the LICENSE.MD file is blank. You should populate the license file to be explicit about your intent and the rights retained by you and offered/compelled by your users.

WriteDummyDBF in WriteGeometryCollection Method

Having some problems with my DBF-file is getting it's header overwritten when writing the collection of shapes to disk.
Found that it's actually a line in the WriteGeometryCollection-method that overwrites my DBF-file that I already have created.

I don't like this design since it's not clear for the one using NTS that the DBF-file needs to be written after the shape-file.
Shouldn't we add a check here and not create the DummyDbf (if it should be there at all) if the DBF-header of DbfWriter already have been written. Of if the DBF-file already exists.

https://github.com/NetTopologySuite/NetTopologySuite/blob/master/NetTopologySuite.IO/NetTopologySuite.IO.GeoTools/ShapefileWriter.cs#L188

https://github.com/NetTopologySuite/NetTopologySuite/blob/master/NetTopologySuite.IO/NetTopologySuite.IO.GeoTools/ShapefileWriter.cs#L204

Envelope class does not accept ICoordinates as method params

With coordinates from a third party library implementing GeoAPI

ICoordinate c1 = SomeExternalLib.MakeSomeCoordinate();
ICoordinate c2 = SomeExternalLib.MakeSomeCoordinate();

Shouldn't i be able to do this

Envelope env = new Envelope(c1, c2);

At the moment I have to do either this

Envelope env = new Envelope(c1.X, c2.X, c1.Y, c2.Y);

Or this

Coordinate c1geoapi = Coordinate(c1.X,c1.Y);
Coordinate c2geoapi = Coordinate(c2.X,c2.Y);
Envelope env = new Envelope(c1, c2);

Or use the deprecated IEnvelope interface which of course gives me deprecation warnings.

Remove redundant interface members

Every member defined on an interface represents an added cost to whoever is ultimately going to implement it. Some of our interfaces have gotten way out of hand, and #30* seeks to help with that by segregating the interfaces more so that the implementer doesn't have to account for everything under the sun.

  • *looking at just the original issue, not what the comments turned it into

However, we could get some "quick wins" towards usability by removing some members that are outright redundant with other members already on the same interface (adding extension methods in their place where appropriate to avoid harming usability).

I propose that we try to simplify as much of this list as we reasonably can...

ICoordinateBuffer

AddCoordinate(...) is redundant with InsertCoordinate(Count, ...), but can we just get rid of this interface?

ICoordinateSequence

Ordinate / Ordinates and friends... that's a whole other topic of its own.

GetCoordinateCopy(i) is equivalent to GetCoordinate(i, CreateCoordinate()).

ToCoordinateArray() is a bunch of GetCoordinateCopy(i) calls to initialize new Coordinate[Count].

ExpandEnvelope(env) is a bunch of calls to env.ExpandToInclude(GetX(i), GetY(i)).

ICoordinateSequenceFactory

Again, leaving out Ordinate / Ordinates and friends.

ICoordinateSequence Create(int size, int dimension, int measures) is all that implementations should need to care about implementing.

"Create it as a copy of this other thing" can have a major impact on performance for pretty much every implementation (there's almost always a better way to copy from an instance of the same type), however, I think we can satisfy that need almost as well with a new "default interface method"*:

public interface ICoordinateSequence
{
    /* ... */

    void CopyFrom(ICoordinateSequence other, int offset, int count, IEnumerable<Ordinate> ordinatesToCopy)
    {
        // not writing parameter validation here
        var ordinatesToCopyArray = ordinatesToCopy.ToArray();
        for (int i = 0; i < count; i++)
        {
            foreach (var ordinate in ordinatesToCopyArray)
            {
                this.SetOrdinate(i, ordinate, other.GetOrdinate(i + offset, ordinate));
            }
        }
    }
}

*I know that we can't do default interface methods properly, but there's a way to cheat at it that's almost as good... instead of a true "default interface method", we can use an extension method with a helper interface... to give an idea, an interface with a "default method" that we wish we could write like this:

public interface ISampleInterface
{
    void DoTheThing() => Console.WriteLine("I am doing the thing, but not very well");
}

could be delivered like this:

public interface ISampleInterface
{
    // DoTheThing is *NOT* here.
}

public interface IDoTheThingBetter
{
    void DoTheThing();
}

public static class SampleInterfaceExtensions
{
    public static void DoTheThing(this ISampleInterface @this)
    {
        if (@this is IDoTheThingBetter thingDoer)
        {
            // "overridden" implementation
            thingDoer.DoTheThing();
            return;
        }

        // default implementation
        Console.WriteLine("I am doing the thing, but not very well");
    }
}

ICurve

IsClosed is the same as checking whether StartPoint and EndPoint are equal.

IsRing is apparently IsClosed && IsSimple, according to its single implementation that isn't called by anyone I can discover right now.

IGeometry

Strict redundancies

  1. SRID is Factory.SRID.
  2. GeometryType looks like GetType().Name???
  3. Envelope is Factory.ToGeometry(EnvelopeInternal).
  4. Normalized() is Copy().Normalize() + return the normalized copy.
  5. EqualsExact(g) is EqualsExact(g, 0).
  6. EqualsNormalized(g) is Normalized().EqualsExact(g.Normalized()).
  7. PointOnSurface is InteriorPoint.
  8. x.Within(y) is y.Contains(x).
  9. x.CoveredBy(y) is y.Covers(x).
  10. x.Disjoint(y) is !x.Intersects(y).
  11. Relate(g, somePattern) is Relate(g).Matches(somePattern).
  12. Buffer(double, IBufferParameters) is the only Buffer method we need.
    • though I'd kinda like IBufferParameters not to be an interface...

Can be implemented via a call to Apply(...)

  1. int NumGeometries
  2. int NumPoints
  3. Coordinate Coordinate
  4. Coordinate[] Coordinates
  5. double[] GetOrdinates(Ordinate)
  6. Dimension Dimension (but OgcGeometryType will often be enough)
  7. IGeometry Envelope
  8. Envelope EnvelopeInternal
  9. bool IsEmpty

Can be implemented via Relate(g), though there's often a decent way to short-circuit.

  1. Contains / Within
  2. Covers / CoveredBy
  3. Intersects / Disjoint
  4. Touches
  5. Crosses
  6. Overlaps
  7. EqualsTopologically

IGeometryCollection

  1. int Count is NumGeometries
  2. this[int] is GetGeometryN

IGeometry[] Geometries also could be this.ToArray() if we're OK with no longer defining it as a view of the underlying data... not exactly a discussion for here though.

IGeometryFactory

These methods are variants of other methods invoke those other methods with some sort of "empty":

  1. CreatePoint()
  2. CreateLineString()
  3. CreateLinearRing()
  4. CreatePolygon()
  5. CreatePolygon(ILinearRing)
  6. CreateMultiPoint()
  7. CreateMultiLineString()
  8. CreateMultiPolygon()
  9. CreateGeometryCollection()

These methods are variants of other ICoordinateSequence methods via CoordinateSequenceFactory:

  1. CreatePoint(Coordinate)
  2. CreateLineString(Coordinate[])
  3. CreateLinearRing(Coordinate[])
  4. CreatePolygon(Coordinate[])
  5. CreateMultiPointFromCoords(Coordinate[])

Finally, CreatePolygon(ICoordinateSequence) is CreatePolygon(CreateLineString(seq))

ILineString

  1. GetCoordinateN(i) is CoordinateSequence.GetCoordinate(i)
  2. GetPointN(i) is Factory.CreatePoint(GetCoordinateN(i))

IMultiCurve

bool IsClosed is !IsEmpty && Cast<ICurve>().All(g => g.IsClosed)

IPoint

X is CoordinateSequence.GetX(0). Same for Y, Z, M.

IPolygon

Same idea as in IGeometryCollection, we only need either the array or the Num +

  1. ExteriorRing is Shell.
  2. ILineString[] InteriorRings is Holes.ToArray<ILineString>()
  3. int NumInteriorRings / GetInteriorRingN(int) come from Holes, or vice-versa if we don't want to keep defining Holes as a view of the underlying data.

IPrecisionModel

bool IsFloating, int MaximumSignificantDigits, and void MakePrecise(Coordinate) are all defined to be the same as their NTS implementations.

IGeometryServices

CreatePrecisionModel(IPrecisionModel) is one of the two other overloads depending on the type.

All CreateGeometryFactory overloads are equivalent to CreateGeometryFactory(IPrecisionModel, int, ICoordinateSequenceFactory), filling in the defaults from properties where missing.

Add a way to bootstrap GeometryServiceProvider.Instance *only* if it's still uninitialized

This is directly related to NetTopologySuite/NetTopologySuite#227, where I pointed this out in a comment.

When a downstream assembly implements GeoAPI, I expect that 99.99% of the time, that assembly has its own type that implements IGeometryServices and is expected to be the "go-to" implementation for that assembly. So when that assembly is used for the first time, it would make sense for that assembly to tell GeoAPI "hey, in case you're still looking for something to use for GeometryServiceProvider.Instance, here's one for you!", without overriding any explicit preferences that the application has already set.

In "fat" .NET target frameworks (for backwards compat reasons), when GeometryServiceProvider.Instance hasn't been explicitly initialized, the getter does its own search of the entire AppDomain looking for something that fits.

This has a few flaws:

  1. Not all .NET Standard target frameworks have what we need out-of-the-box to make this work.
  2. The search might pick up an implementation of IGeometryServiceProvider that wasn't intended to be used as a "go-to" implementation (perhaps the first thing it sees could be a "fake" that stubs out all but the specific things that a specific usage might need).
  3. There's no way for an intermediate downstream assembly to tell GeoAPI about an instance that it should use only if someone else hasn't already set their own value explicitly, not even a clean way to check if the value has already been set explicitly.
  4. The reflection-based walking is probably kinda slow.

I propose that we add something to GeometryServiceProvider that looks something like this:

public static bool SetInstanceIfUninitialized(IGeometryServices instance)
{
    return Interlocked.CompareExchange(ref _instance, instance, null) == null;
}

The return value signals true if Instance will now start using the new value, false otherwise. The return value probably won't be used, but it's basically free and maybe it could be used for logging purposes.

This directly resolves bullet point 3 from the above list.

It also allows NetTopologySuite/NetTopologySuite#227 to directly resolve bullet points 2 and 4, and indirectly resolve bullet point 1, in what's probably an extremely common case of "GeoAPI, implemented by NetTopologySuite".

There's not much of a downside to doing this in GeoAPI (downsides would be enumerated on a concrete implementation, such as the fix for NetTopologySuite/NetTopologySuite#227).

This should wait for a conclusion to the #40 / #39 story, because that directly affects this.

Problem with create a new DBF-file with DBaseFileWriter

When using DBaseFileWrite to create a new DBF-file with NTS 1.13.4 some problems have occured that did not exist in earlier versions of NTS.

One problem is that I'm not able at all to create a DBF-file at all since the ValidateDataPath is set to true and the file that I'm trying to create of course does not exist.

Is it something wrong here:
https://github.com/NetTopologySuite/NetTopologySuite/blob/master/NetTopologySuite.IO/NetTopologySuite.IO.GeoTools/Dbase/DbaseFileWriter.cs#L38

Shouldn't third parameter be false since the file does not exist when trying to create it?

Redesign GeoAPI

If I understood @DGuidi correctly, GeoAPI started off by trying to implement some early OGC - GeoAPI specification.

Due to lack of resources it never got that far and instead it ended up as a mix of early GeoAPI (CoordinateSystem namespace ) along with a set of interfaces extracted from early NetTopologySuite classes (matching JTS 1.7, iirc).

Now there is the Support Spatial Datatypes issue around. In the course of the discussion someone suggested to use NetTopologySuite/GeoAPI to achive that, and currently it seems at least to be investigated as an option.

I propose the following:

  • Create a core GeoAPI library that contains all necessary interfaces to describe and persist geometries
  • Create an additional GeoAPI library that covers all the spatial operations on those core GeoAPI geometries.

Are there other ideas around?

Get permissions from all contributors (at least all who have made significant changes) to agree to license change.

This is the GeoAPI version of NetTopologySuite/NetTopologySuite#238. I'm assuming that people who have already given their consent on that issue are likely to give consent on this one, so I'm not going to immediately go through the effort of linking their individual commits.

Authors who seem to have made significant contributions (these are the only ones whom I will mention with @ where a GitHub name is available):

Authors whose contributions to code still in develop strictly seem small enough not to be worth fretting over (this is based on judgment calls, so not crossing out the authors yet):

  • Peet Whittaker / @\peetw (c8f2452)

No license file

I can't find any licensing information in this repository.

Probably it is still LGPL as previously stated at the old CodePlex site (https://geoapi.codeplex.com/license), but it would be nice to be explicit about it on GitHub also.

Thank you from a long time user :-)

Remove ICloneable implementations across the board

ICloneable should not be exposed in public APIs. The contract is ambiguous (deep or shallow? full or partial?), and so everybody downstream who relies on that interface (independently of, e.g., IGeometry) would need to know more specific details in order to be confident that the object will be cloned the way that they expect.

These "specific details" can come just as well from the contracts of more specific Copy methods that we have on such interfaces, so let's remove all our implementations of the less specific ICloneable.

Suggestion: make two sets of interfaces - data and methods

Hello,

I have a file with data as geojson. I want to load this in and do some operations on the data (for example checking if a point is inside a polygon) with the use of NTS. For reading in the geojson data I wanted to use GeoJSON. Unfortunally it is not easy to convert (cast) the geometries from that library to the ones NTS is using.

Then I found this GeoApi project with its goal to make geo libraries more compatible with each other. The GeoJSON project is not using this library. I therefore forked it to find out if it is easy to add the different interfaces to the geometry classes in the GeoJSON project. Unfortunately by using the IPoint interface from GeoAPI I also need to implement all kind of geometric operations. Something which is already implemented in NTS.

Should the interfaces not be split up in pure data container interfaces and interfaces describing the available methods for a geometry. This way I can easily cast a geometry created by the GeoJSON library over to NTS.

Would love to hear your feedback.

Johan

Target just .NET Standard 2.0

Multi-targeting the legacy platforms is an annoying limitation.

At some point, we should trim the targeted list down to just .NET Standard 2.0, both so that we have access to more APIs and to ease future maintenance.

[Enhancement] Performance-Friendly IMathTransform Alternative

The GeoAPI.CoordinateSystems.Transformations.IMathTransform API is sub-par. Unless the implementer and consumer mutually agree on a protocol that would allow outputs to be pooled (which is stricter than what GeoAPI demands), it pretty much forces all implementations to allocate a whole new object on the managed heap for every call to hold the return value.

This is pretty bad, and TransformList methods don't help this at all... in fact, they can make it worse, because in exchange for reducing virtual calls compared to the alternatives, they force all the inputs and outputs to be allocated at once, which (beyond a certain list size) will guarantee that they get tenured.

For a while, we were using our own Geotools.NET at work, and we solved this with just a void Transform(ref double x, ref double y). PackedDoubleCoordinateSequence.GetRawCoordinates() gives us what we need to use that method to project / unproject without any temporary allocations.

Obviously, it's a lot more complicated to do this in GeoAPI / ProjNet4GeoAPI, since there are external consumers. Any thoughts about how we could make this better?

GeoAPI 1.7.4 to 1.7.5 broke come code

After updating to GeoAPI 1.7.5 I now get the following errors:

1>Helpers\GeoConversions.cs(20,57,20,92): error CS7069: Reference to type 'IProjectedCoordinateSystem' claims it is defined in 'GeoAPI', but it could not be found
1>Helpers\GeoConversions.cs(21,76,21,81): error CS7069: Reference to type 'IGeographicCoordinateSystem' claims it is defined in 'GeoAPI', but it could not be found
1>Helpers\GeoConversions.cs(24,29,24,63): error CS7069: Reference to type 'ICoordinateTransformation' claims it is defined in 'GeoAPI', but it could not be found

        public static UtmPosition LatLonToUtm(double latitude, double longitude)
        {
            var zone = CalcUtmZone(longitude);
            var isNorthernHemisphere = latitude >= 0;
            IProjectedCoordinateSystem utmCoordSystem = ProjectedCoordinateSystem.WGS84_UTM(zone, isNorthernHemisphere);
            IGeographicCoordinateSystem wgs84 = GeographicCoordinateSystem.WGS84;
            CoordinateTransformationFactory ctFact = new CoordinateTransformationFactory();

            var transform = ctFact.CreateFromCoordinateSystems(wgs84, utmCoordSystem);
            var lonLat = transform.MathTransform.Transform(new[] { longitude, latitude });

            var latZone = UtmPosition.GetUtmLatitudeZoneLetter(latitude);

            return new UtmPosition(lonLat[0], lonLat[1], zone, latZone);
        }

Reconsider use of SerializableAttribute

[Serializable] on its own is easy, but it has problems: versioning, lack of control, and fields are opt-out.

If we're going to keep supporting serialization / deserialization for instances of our types, then I recommend that we at least implement ISerializable (with (SerializationInfo info, StreamingContext context) constructor) wherever we do.

Though, if you ask me, I think [Serializable] is probably not that helpful in our context to begin with. There are plenty of platform-independent binary / text formats that support copying geometry instances from one place to another. .NET-specific serialization / deserialization on top of that doesn't seem to justify itself.

So one thing we could do instead of ISerializable would be to just remove the [Serializable] tags for v2, see if that actually breaks anybody's workflow, and then consider how best to resolve that, in the context of all the serialization options available now that we're not limited by the APIs supported on v1 platforms.

Replace notable interfaces with abstract classes, for multiple reasons

As a sort-of alternative to #67, if we replace interfaces like IGeometry with abstract classes like GeometryBase, then we can provide a much better experience for implementers while still retaining the same essential API shape (without resorting to "tricks" to make almost-"default interface methods" happen).

I expect that this will be somewhat more work than #67 to get up and running, but I also claim that it is likely to be a much better experience for all parties (except maybe the OGC folks, who would likely be indifferent because it's not really in the scope of what they care about).

These are the interfaces that I propose replacing with abstract classes:

Common Themes

  1. FooCore methods are protected members that subclasses may (or must) override which are used to implement one or more non-virtual Foo members.
    • These exist instead of making Foo itself virtual / abstract, because there's often surface-level parameter validation / short-circuiting that all implementations of Foo can legally do the same way, so why force every implementer to repeat it?
  2. I would like to figure out the "right" way to handle Ordinate / Ordinates / Dimension / Measures.
    • For now, I'll pretend like we've resolved it in a way that defines GetOrdinate(i, Ordinate.Z) as always being identical to GetZ(i); if we resolve it differently, then some things will have to adjust.

IPreparedGeometry

This would be a subset of NTS's BasicPreparedGeometry. Accepts a geometry instance in the constructor that it uses, by default for all the operations. And that's it.

No abstract members; an empty subclass would be completely functional (but uninteresting).

ICoordinateSequence

Constructors

  1. protected CoordinateSequenceBase(int count, Ordinates includedOrdinates)
    • count >= 0
    • πŸ€” validate that includedOrdinates has at least theOrdinates.XY flags?
    • πŸ€” validate that includedOrdinates has at most the Ordinates.XYZM flags?
  2. protected CoordinateSequenceBase(CoordinateSequenceBase copyFrom)
    • Invoke the other constructor using the values of copyFrom

Abstract methods

  1. double GetOrdinateCore(int i, Ordinate ordinate)
  2. void SetOrdinateCore(int i, Ordinate ordinate, double value)
  3. CoordinateSequenceBase Copy();

Virtual methods

  1. Coordinate CreateCoordinate()
    • Default is to create Coordinate, CoordinateZ, CoordinateM, or CoordinateZM as appropriate for our ordinate mask, otherwise throw NotSupportedException.
      • NotSupportedException path could be skipped if we do both πŸ€” constructor validations.
  2. Envelope ExpandEnvelope(Envelope env)
    • Default does the obvious loop.
    • Subclass might want control of the loop for performance reasons.
  3. Coordinate GetCoordinateCore(int i)
    • Default calls CreateCoordinate and initializes as appropriate.
    • Subclass might want to override to avoid allocating and copying.
  4. Coordinate GetCoordinateCopyCore(int i)
    • Default calls CreateCoordinate and initializes as appropriate.
    • Subclass might want to override to avoid allocating and copying.
  5. Coordinate[] ToCoordinateArray()
    • Default creates the array the obvious way
    • Subclass might want to override to avoid allocating and copying.
  6. void CopyFromCore(CoordinateSequenceBase other, int offset, int count)
    • Default copies ordinates.
    • Subclass will very likely want to override for performance reasons to avoid virtual call overhead and (perhaps) to use direct array copying if the source stores its data in a compatible format.

Other discussion

Other methods are non-virtual and implemented only in terms of what we have available above.

ICoordinateSequenceFactory

Constructors

  1. protected CoordinateSequenceFactoryBase(Ordinates maxOrdinates)
    • πŸ€” validate that includedOrdinates has at least theOrdinates.XY flags?
    • πŸ€” validate that includedOrdinates has at most the Ordinates.XYZM flags?

Abstract methods

  1. CoordinateSequenceBase CreateCore(int count, Ordinates ordinates)

Virtual methods

  1. CoordinateSequenceBase CreateCore(CoordinateSequenceBase copyFrom, Ordinates ordinates)
    • Default does something like result = CreateCore(copyFrom.Count, ordinates), then result.CopyFrom(copyFrom), then returns it.
    • Subclass may want to override if initializing an empty sequence involves significant work that would have to get repeated anyway during CopyFrom.

Other discussion

If we want to keep a Create method(s) that accept(s) Coordinate[], should CoordinateArraySequence move up to GeoAPI? It could help a lot, both here and elsewhere...

IGeometry

Constructors

  1. protected GeometryBase(GeometryFactoryBase factory, OgcGeometryType ogcGeometryType)

Abstract members

This still seems like a little too much for implementers to have to implement, but I think we risk going too far the other way if we cut out too much more.

  1. GeometryBase Boundary { get; }
  2. Dimension BoundaryDimension { get; }
  3. GeometryBase ComputeCentroidCore()
  4. GeometryBase ComputeInteriorPointCore()
  5. void Normalize()
  6. GeometryBase Copy()
  7. GeometryBase ConvexHull()
  8. IntersectionMatrix Relate(GeometryBase g)
  9. GeometryBase Overlay(GeometryBase g, SpatialFunction opCode)
    • Not in here yet, but it seems to belong here for the same reason that Relate does...
  10. GeometryBase BufferCore(double distance, BufferParameters bufferParameters)
    • Technically we could keep IBufferParameters, but I doubt that there's any sort of need for a different implementation than the one that's in NTS...
  11. bool EqualsExact(GeometryBase other, double tolerance)
  12. double Distance(GeometryBase other)
  13. void Apply(ICoordinateFilter filter)
  14. void Apply(ICoordinateSequenceFilter filter)
  15. void Apply(IGeometryFilter filter)
  16. void Apply(IGeometryComponentFilter filter)
  17. void GeometryChanged()
  18. byte[] AsBinary()
  19. string AsText()

Virtual members

  1. double Area { get; }
    • Default is 0
  2. double Length { get; }
    • Default is 0
  3. int NumGeometries { get; }
    • Default runs Apply(IGeometryFilter), returns how many times Filter was called.
  4. int NumPoints { get; }
    • Default runs Apply(ICoordinateSequenceFilter), returns how many times Filter was called.
  5. Coordinate Coordinate { get; }
    • Default runs Apply(ICoordinateFilter) and returns the first one.
  6. Coordinate[] Coordinates { get; }
    • Default runs Apply(ICoordinateFilter) and returns all of them.
  7. double[] GetOrdinates(Ordinate ordinate)
    • Default runs Apply(ICoordinateSequenceFilter) and returns the values.
  8. Dimension Dimension { get; }
    • Default checks the OgcGeometryType.
      • All defined values other than GeometryCollection have a corresponding result.
      • For GeometryCollection, run Apply(IGeometryFilter) and return the max it sees (or False).
      • Undefined values throw NotSupportedException.
  9. Envelope EnvelopeInternal { get; }
    • Default runs Apply(ICoordinateSequenceFilter), returns an Envelope that contains all.
  10. GeometryBase GetGeometryN(int n)
    • Default is itself for 0, otherwise runs Apply(IGeometryFilter) and returns the nth value.
  11. Methods that NTS implements ultimately via Relate
    • Default is to just use Relate.
    • Special mention, only have one of the methods in each of the following pairs be virtual:
      • Contains / Within
      • Covers / CoveredBy
      • Intersects / Disjoint
  12. Methods that NTS implements ultimately via SnapIfNeededOverlayOp
    • Default is to just use Overlay.
  13. bool IsEmpty { get; }
    • Default is to run Apply(ICoordinateSequenceFilter) and return a value based on whether or not Filter was ever called.
  14. bool IsWithinDistance(GeometryBase geom, double distance)
    • Default is to compare distance to the result of Distance(geom)
  15. void GeometryChangedAction()
    • Default is to do nothing.

Other discussion

Union() (the parameterless overload) is of questionable benefit at this layer. It's not OGC, and if everything's valid, then the result is topologically identical to the original one. Plus, it's semantically equivalent to Union(EMPTY). This isn't to say it's not useful, just that it doesn't seem useful here.

If we're going to have things like Area and Centroid on the base (which I actually think makes a ton of sense given that we don't have multiple inheritance), then we should probably also bring up the rest of the OGC methods still sitting on derived interfaces:

  1. ICurve.StartPoint / EndPoint
  2. ICurve.IsClosed
  3. ILineString.PointN
  4. IPoint.X / Y / Z / M
  5. IPolygon.ExteriorRing / NumInteriorRings / GetInteriorRingN

TODO:

IGeometryFactory

IPrecisionModel

Licenses missing

The licenses are mentioned in the nuget packages, but those are very hard to find when searching for the license. You should add License files in the base directories.

IEquatable<T> Is A Bad Idea On Unsealed Types

IEquatable<T> exists for basically one purpose only: to avoid the performance-related overhead of casting + boxing/unboxing overhead of object when an instance of the type is stored in a hash-based collection. Without the concern of performance, bool Equals(object) would be sufficient. So if type Foo is expected to be used as the key in a hash-based collection, especially if it's a value type, it is sometimes recommended that Foo should implement IEquatable<Foo>.

I've never seen a use case where it is useful for an interface type IFoo to implement IEquatable<IFoo>, and every time I have seen this at work, it has been a mistake. Same goes for the NTS projects, it seems.

I'm pretty sure this actually makes GeoAPI's GeoAPI.Geometries.IGeometry differ semantically from JTS's org.locationtech.jts.geom.Geometry, because the latter just uses the Java equivalent to .NET's bool Equals(object obj), which uses boolean equalsExact(Geometry other), for all Java collections:

  • new Dictionary<ILineString, string>() will use bool Equals(object obj) to compare keys.
  • new Dictionary<Geometry, string>() will use bool Equals(object obj) to compare keys.
  • new Dictionary<IGeometry, string>() will use bool Equals(IGeometry other) to compare keys.

It's possible to "fix" IEquatable<T> and keep it around by taking some breaking changes, but the result would be expensive to implementers and confusing to maintainers and consumers alike. I think we should consider a breaking change to drop every IEquatable<T> from this repository, with one exception: Interval is actually recommended to implement this interface, because it's a struct type.

After, we should consider whether or not to add bool Equals(IGeometry geometry) itself to IGeometry.

  • I personally think we shouldn't have that on IGeometry because it already has both bool EqualsExact(IGeometry other) and bool EqualsTopologically(IGeometry other).
  • JTS javadoc mentions that its boolean equals(Geometry g) is only there "for backward compatibility reasons" now that equalsTopo exists.
  • This is tricky to do, ourselves, in such a way that the result is both backwards-compatible and faithful to JTS. Perhaps what we should do is keep bool Equals(IGeometry other) around, but mark it with [Obsolete(..., error: true)] to force consumers to explicitly say EqualsTopologically if that's what they want.

I have similar thoughts about IComparable<T>, but that's a trickier subject because we inherited some of that messiness from JTS, so I'm not sure what I want to propose that we do about that one yet. It'll be a separate issue, if anything.

Migrating to .net core

Hi.

I used to have this method to convert my coordinates to the right format.
How would you write this now?

        public static double[] ConvertCoordinates(string LatitudeDegrees, string LatitudeMinutes, string LatitudeSeconds, string LongitudeDegrees, string LongitudeMinutes, string LongitudeSeconds)
        {
            ICoordinateSystem utm = ProjectedCoordinateSystem.WGS84_UTM(33, Convert.ToDouble(LatitudeDegrees) + (Convert.ToDouble(LatitudeMinutes) / 60) + (Convert.ToDouble(LatitudeSeconds) / 3600) > 0);
            ICoordinateTransformation trans = new CoordinateTransformationFactory().CreateFromCoordinateSystems(GeographicCoordinateSystem.WGS84, utm);

            return trans.MathTransform.Transform(new double[] {
                    Convert.ToDouble(LongitudeDegrees) + (Convert.ToDouble(LongitudeMinutes) / 60) + (Convert.ToDouble(LongitudeSeconds) / 3600),
                    Convert.ToDouble(LatitudeDegrees) + (Convert.ToDouble(LatitudeMinutes) / 60) + (Convert.ToDouble(LatitudeSeconds) / 3600)
                }
            );
        }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.