Skip to content

Conversation

@probins
Copy link
Contributor

@probins probins commented Mar 19, 2016

I tested my changes mentioned in #3953 on a GeometryCollection, and found they didn't work. However, when I tried doing the same with the current master, I found that didn't work either. examples/geojson has a GeometryCollection so if you do something like

format=new ol.format.GeoJSON();
format.writeFeature(vectorSource.getFeatures()[6], {featureProjection:'EPSG:3857'});

you can see that the coordinates are all screwy. The reason for this is that writeGeometry_ is getting run for the Collection as a whole and then for each individual geometry. writeGeometry_ runs ol.format.Feature#transformWithOptions(), so the coordinates for each geometry are transformed twice. This PR calls write for the individual geoms without the projection options, so the 2nd transform doesn't occur.

From the fact that no-one's noticed this before, I conclude that GeometryCollections aren't used very much. :-) I think tests should be added for this case, but would prefer to include that in my fixes for #3953 so the rounding can be tested as well.

@probins probins closed this Mar 19, 2016
@probins probins reopened this Mar 19, 2016
var options = (opt_options && opt_options.rightHanded) ? {
rightHanded: opt_options.rightHanded
} : undefined;
return ol.format.GeoJSON.writeGeometry_(geometry, options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably safer to do something like

var options = ol.object.assign({}, opt_options);
delete options.featureProjection;
return ol.format.GeoJSON.writeGeometry_(geometry, options);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shorter too :-) ok, will change this

@ahocevar
Copy link
Member

I think tests should be added for this case, but would prefer to include that in my fixes for #3953 so the rounding can be tested as well.

I'd feel better if you added a test for this pull request too. You can use something like exepct(1.1).to.roughlyEqual(1.10001, 0.0001);.

@marcjansen
Copy link
Member

What exactly would that test?

@tschaub
Copy link
Member

tschaub commented Mar 20, 2016

What exactly would that test?

I think @ahocevar is just saying that you can use the roughlyEqual() matcher in testing (e.g. expect(point.getCoordinates()[0]).to.roughlyEqual(10, 1e-4)).

Thanks for catching this and providing a fix @probins. I agree we should have tests before merging.

var geometries = geometry.getGeometriesArray().map(function(geometry) {
return ol.format.GeoJSON.writeGeometry_(geometry, opt_options);
var options = ol.object.assign({}, opt_options);
delete options.featureProjection;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to delete options.dataProjection as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's not necessary. If featureProjection isn't set, no transform is performed.

@probins
Copy link
Contributor Author

probins commented Mar 20, 2016

I think @ahocevar is just saying that you can use the roughlyEqual() matcher in testing (e.g. expect(point.getCoordinates()[0]).to.roughlyEqual(10, 1e-4)).

where is roughlyEqual defined? I couldn't find any docs

@marcjansen
Copy link
Member

@probins
Copy link
Contributor Author

probins commented Mar 20, 2016

ok. Basic test added, based on the Point test above.

expect(geometries[0].getCoordinates()[0]).to.roughlyEqual(
gotGeometries[0].getCoordinates()[0], 1e-8);
expect(
Math.abs(geometries[0].getCoordinates()[1] -
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also use roughlyEquals here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I was wondering why the Point test wasn't using roughlyEquals for both coordinates

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

roughlyEqual is just for numbers, so you have to test x and y of a coordinate separately or in a forEach function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the 'transforms and encodes a point' test is using roughlyEqual for the x coord and this Math.abs formula for the y. I'm wondering why.

@probins
Copy link
Contributor Author

probins commented Mar 21, 2016

test changed as suggested, so this tests a Point and the first coordinate of a LineString within a GeometryCollection, which should be sufficient.

I'll submit another PR to change the Point test to use roughlyEqual for both coords - might as well make these things consistent.

ahocevar added a commit that referenced this pull request Mar 21, 2016
Fix geojson write GeometryCollection
@ahocevar ahocevar merged commit cf6baf2 into openlayers:master Mar 21, 2016
@ahocevar
Copy link
Member

I'll submit another PR to change the Point test to use roughlyEqual for both coords - might as well make these things consistent.

Thanks. I think a roughlyEqualCoordinate method could also make sense.

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

Successfully merging this pull request may close these issues.

4 participants