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

Add a marker feature. #1035

Merged
merged 2 commits into from
Mar 9, 2020
Merged

Add a marker feature. #1035

merged 2 commits into from
Mar 9, 2020

Conversation

manthey
Copy link
Contributor

@manthey manthey commented Sep 26, 2019

This adds an efficient webgl marker feature. It uses slightly more memory than the point feature (one more float value per marker is passed to the GPU than for points). A variety of shapes are defined: ellipses, rectangles, isosceles triangles, and ovals, plus stellations of each of these. The shapes can specify orientation, and can automatically scale and/or rotate with the map.

There is one distinct difference between markers and points. The radius of the marker is the total radius, including any stroke. The size of the point is the combination of the radius and the stroke.

These use nearly the same vertex shaders as the point feature, but a vastly more complex fragment shader. As such, rendering complex shapes will saturate the GPU sooner than for basic points.

At some future point, it is intended to add image markers, where images or svgs could be rendered via a texture map. In this case, the intent is to use a single texture buffer and pack multiple images into it with a small space between each.

Resolves #820 (though a new issue should be created for image/svg markers).

@manthey
Copy link
Contributor Author

manthey commented Sep 26, 2019

Try this out here . Switch the if (false) to if (true) on line 40 to see lots of markers. This is extracted from the tutorial that is part of this PR.

@manthey
Copy link
Contributor Author

manthey commented Sep 26, 2019

@aashish24 This PR has several immediate uses: it provides an efficient ellipse drawing method, which will be of use in HistomicsTK, and it will make a good head symbols for the upcoming track feature.

@manthey
Copy link
Contributor Author

manthey commented Oct 7, 2019

One change that might be desired is where strokes are conceptually located. For the point feature, the stroke is outside the specified radius. For polygons, the stroke's default position is centered on the edge of the polygon (though this can be changed with the strokeOffset style property). Currently, on markers, the stroke is inside the specified radius.

This doesn't make too much different when the marker is a fixed size. There is an option to scale the radius and/or the stroke with the map's scale. If the radius is scaled but not the stroke, this is done by treating the specified radius and stroke width as the values at zoom 0. The scaled radius is computed as (radius at zoom 0 - stroke width) * 2^(zoom level) + stroke width. If one conceptually wants the stroke to fixed in size and centered on a radius that changes with zoom, this really should be (radius at zoom 0 - (stroke width) / 2) * 2^(zoom level) + (stroke width) / 2.

Should this be an option? Or should zoomWithMap using a zooming radius but not a stroke use a different default? Opinions welcome.

@manthey
Copy link
Contributor Author

manthey commented Oct 14, 2019

I've added a strokeOffset option to markers.

This is useful, for instance, when using the ellipse marker and having the ellipse scale with the map. Setting the strokeOffset to 0 gives behavior similar to a polygon.

Setting the strokeOffset to 1 allows setting the radius and strokeWidth in the same manner as the pointFeature.

The default strokeOffset of -1 allows the radius to be the actual maximal size of the marker.

@manthey
Copy link
Contributor Author

manthey commented Oct 16, 2019

I'll note that due to fragment shader floating point precision, markers over a certain size probably won't look right. This size is probably a radius on the order of 2**(half the number of bits of highp + one or two), so ~2^13 or ~2^14 or ~8192 or ~16384 pixels. If a GPU uses lower maximum precision in its fragment shader, this will degrade further.

This adds an efficient webgl marker feature.  It uses slightly more
memory than the point feature (one more float value per marker is passed
to the GPU than for points).  A variety of shapes are defined: ellipses,
rectangles, isosceles triangles, and ovals, plus stellations of each of
these.  The shapes can specify orientation, and can automatically scale
and/or rotate with the map.

There is one distinct difference between markers and points.  The radius
of the marker is the total radius, including any stroke.  The size of
the point is the combination of the radius and the stroke.

These use nearly the same vertex shaders as the point feature, but a
vastly more complex fragment shader.  As such, rendering complex shapes
will saturate the GPU sooner than for basic points.

At some future point, it is intended to add image markers, where images
or svgs could be rendered via a texture map.  In this case, the intent
is to use a single texture buffer and pack multiple images into it with
a small space between each.

Resolves #820 (though a new issue should be created for image/svg
markers).
This is useful, for instance, when using the ellipse marker and having
the ellipse scale with the map.  Setting the strokeOffset to 0 gives
behavior similar to a polygon.

Setting the strokeOffset to 1 allows setting the radius and strokeWidth
in the same manner as the pointFeature.

The default strokeOffset of -1 allows the radius to be the actual
maximal size of the marker.
@aashish24
Copy link
Member

One change that might be desired is where strokes are conceptually located. For the point feature, the stroke is outside the specified radius. For polygons, the stroke's default position is centered on the edge of the polygon (though this can be changed with the strokeOffset style property). Currently, on markers, the stroke is inside the specified radius.

This doesn't make too much different when the marker is a fixed size. There is an option to scale the radius and/or the stroke with the map's scale. If the radius is scaled but not the stroke, this is done by treating the specified radius and stroke width as the values at zoom 0. The scaled radius is computed as (radius at zoom 0 - stroke width) * 2^(zoom level) + stroke width. If one conceptually wants the stroke to fixed in size and centered on a radius that changes with zoom, this really should be (radius at zoom 0 - (stroke width) / 2) * 2^(zoom level) + (stroke width) / 2.

Should this be an option? Or should zoomWithMap using a zooming radius but not a stroke use a different default? Opinions welcome.

I am not seeing this is a needed thing but perhaps some projects need it? But if it is only a quick change and quick testing then yes I would think that we can have this as an option.

@manthey
Copy link
Contributor Author

manthey commented Nov 5, 2019

I am not seeing this is a needed thing but perhaps some projects need it? But if it is only a quick change and quick testing then yes I would think that we can have this as an option.

I've already added it as an option. When using the marker as a general ellipse, it is nice to have the strokeOffset be 0 so that it behaves much like the default polygon. For markers, it is nice to have the strokeOffset be -1 so that the radius really is the size of the marker.

@manthey manthey changed the base branch from shared-shader-code to master November 5, 2019 17:53
@aashish24
Copy link
Member

@manthey I am looking into this PR

@manthey
Copy link
Contributor Author

manthey commented Dec 2, 2019

@aashish24 Have you had a chance to review this?

Copy link
Member

@aashish24 aashish24 left a comment

Choose a reason for hiding this comment

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

this is pretty useful feature

@manthey manthey merged commit f36a947 into master Mar 9, 2020
@manthey manthey deleted the marker-feature branch March 9, 2020 14:47
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.

Marker feature
2 participants