Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LineString buffer not working as expected #216

Closed
tsuz opened this issue Feb 22, 2021 · 6 comments
Closed

LineString buffer not working as expected #216

tsuz opened this issue Feb 22, 2021 · 6 comments

Comments

@tsuz
Copy link

tsuz commented Feb 22, 2021

Previous: #215

What

Initial, generated and output data

print image
print("initial data", json) Screen Shot 2021-02-22 at 10 47 41
expected (red line) observed
Screen Shot 2021-02-22 at 10 47 41 copy Screen Shot 2021-02-22 at 10 49 38
         if let json = String(data: collection, encoding: .utf8) {
           print("initial data", json)
        } 

        for feature in featureCollection.features {
            if case let .lineString(lineString) = feature.geometry {
                linestrings.append(lineString)
                if let data = try? JSONEncoder().encode(lineString) {
                    let json = String(data: data, encoding: .utf8)
                    print("item json", json)
                }
                guard let buf = try? lineString.buffer(by: 1).geometry else {
                    return
                }
                if let data2 = try? JSONEncoder().encode(buf) {
                    let json = String(data: data2, encoding: .utf8)
                    print("item json 2", json)
                }
            }
        }

Can anyone see what I'm doing wrong here?

@macdrevx
Copy link
Member

In GEOSwift, everything is just math, so since your input geometry is in lat/long coordinates, buffer(1) means that you're trying to buffer by 1 degree of latitude and 1 degree of longitude, which, based on the description is not what you want. Try using a much smaller value.

@macdrevx
Copy link
Member

That said, I'll admit that I'm confused by the output shape. I'll take a closer look at that.

@tsuz
Copy link
Author

tsuz commented Feb 22, 2021

@macdrevx

Thanks for the fast reply!

I assumed the buffer(width: Double) was in meters. After updating this to a smaller value, it worked as expected!

guard let buf = try? lineString.buffer(by: width).geometry else {
  return
}

(*note the original data of the two items below are slightly different but it's in a similar lat/lng)

width=0.0001 width=0.0005
Screen Shot 2021-02-22 at 11 15 38 Screen Shot 2021-02-22 at 11 18 28

Thanks again!

@tsuz tsuz closed this as completed Feb 22, 2021
@macdrevx
Copy link
Member

I did a little more investigation into this issue and discovered that GEOSwift is passing 0 for the quadsegs parameter of geos's buffer function which is leading to some of those flat edges around the outside of the buffered corners. In another location internally, GEOS uses a value of 8 as a default, which results in a result that is closer to what you might expect on first glance. I'll push an update with this change.

@macdrevx
Copy link
Member

Here's the before and after:

quadsegs=0 quadsegs=8
quadsegs=0 quadsegs=8

@macdrevx
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants