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 gcs option to pointSearch and polygonSearch. #1051

Merged
merged 1 commit into from
Apr 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions src/feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,13 @@ var feature = function (arg) {
* Search for features containing the given point. This should be defined in
* relevant subclasses.
*
* @param {geo.geoPosition} geo Coordinate in interface gcs.
* @param {geo.geoPosition} geo Coordinate.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {geo.feature.searchResult} An object with a list of features and
* feature indices that are located at the specified point.
*/
this.pointSearch = function (geo) {
this.pointSearch = function (geo, gcs) {
// base class method does nothing
return {
index: [],
Expand All @@ -195,36 +197,39 @@ var feature = function (arg) {
/**
* Search for features contained within a rectangular region.
*
* @param {geo.geoPosition} lowerLeft Lower-left corner in gcs coordinates.
* @param {geo.geoPosition} upperRight Upper-right corner in gcs coordinates.
* @param {geo.geoPosition} lowerLeft Lower-left corner.
* @param {geo.geoPosition} upperRight Upper-right corner.
* @param {object} [opts] Additional search options.
* @param {boolean} [opts.partial=false] If truthy, include features that are
* partially in the box, otherwise only include features that are fully
* within the region.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {geo.feature.searchResult} An object with a list of features and
* feature indices that are located at the specified point.
*/
this.boxSearch = function (lowerLeft, upperRight, opts) {
this.boxSearch = function (lowerLeft, upperRight, opts, gcs) {
return m_this.polygonSearch([
lowerLeft, {x: lowerLeft.x, y: upperRight.y},
upperRight, {x: upperRight.x, y: lowerLeft.y}], opts);
upperRight, {x: upperRight.x, y: lowerLeft.y}], opts, gcs);
};

/**
* Search for features contained within a polygon. This should be defined in
* relevant subclasses.
*
* @param {geo.polygonObject} poly A polygon as an array of coordinates or an
* object with `outer` and optionally `inner` parameters. All coordinates
* are in map interface gcs.
* object with `outer` and optionally `inner` parameters.
* @param {object} [opts] Additional search options.
* @param {boolean} [opts.partial=false] If truthy, include features that are
* partially in the polygon, otherwise only include features that are
* fully within the region.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {geo.feature.searchResult} An object with a list of features and
* feature indices that are located at the specified point.
*/
this.polygonSearch = function (poly, opts) {
this.polygonSearch = function (poly, opts, gcs) {
// base class method does nothing
return {
index: [],
Expand Down
23 changes: 14 additions & 9 deletions src/lineFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,15 @@ var lineFeature = function (arg) {
* width lines will have a greater selection region than their visual size at
* the narrow end.
*
* @param {geo.geoPosition} p point to search for in map interface gcs.
* @param {geo.geoPosition} p point to search for.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of line indices, `found`:
* a list of lines that contain the specified coordinate, and `extra`: an
* object with keys that are line indices and values that are the first
* segement index for which the line was matched.
*/
this.pointSearch = function (p) {
this.pointSearch = function (p, gcs) {
var data = m_this.data(), indices = [], found = [], extra = {};
if (!data || !data.length || !m_this.layer()) {
return {
Expand All @@ -226,10 +228,11 @@ var lineFeature = function (arg) {
};
}
m_this._updatePointSearchInfo();
var map = m_this.layer().map(),
scale = map.unitsPerPixel(map.zoom()),
var map = m_this.layer().map();
gcs = (gcs === null ? map.gcs() : (gcs === undefined ? map.ingcs() : gcs));
var scale = map.unitsPerPixel(map.zoom()),
scale2 = scale * scale,
pt = transform.transformCoordinates(map.ingcs(), map.gcs(), p),
pt = transform.transformCoordinates(gcs, map.gcs(), p),
strokeWidthFunc = m_this.style.get('strokeWidth'),
strokeOpacityFunc = m_this.style.get('strokeOpacity'),
lineFunc = m_this.line(),
Expand Down Expand Up @@ -264,25 +267,27 @@ var lineFeature = function (arg) {
* Returns lines that are contained in the given polygon.
*
* @param {geo.polygonObject} poly A polygon as an array of coordinates or an
* object with `outer` and optionally `inner` parameters. All coordinates
* are in map interface gcs.
* object with `outer` and optionally `inner` parameters.
* @param {object} [opts] Additional search options.
* @param {boolean} [opts.partial=false] If truthy, include lines that are
* partially in the polygon, otherwise only include lines that are fully
* within the region.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of line indices,
* `found`: a list of lines within the polygon, and `extra`: an object
* with index keys containing an object with a `segment` key with a value
* indicating one of the line segments that is inside the polygon and
* `partial` key and a boolean value to indicate if the line is on the
* polygon's border.
*/
this.polygonSearch = function (poly, opts) {
this.polygonSearch = function (poly, opts, gcs) {
var data = m_this.data(), indices = [], found = [], extra = {}, min, max,
map = m_this.layer().map(),
strokeWidthFunc = m_this.style.get('strokeWidth'),
strokeOpacityFunc = m_this.style.get('strokeOpacity'),
lineFunc = m_this.line();
gcs = (gcs === null ? map.gcs() : (gcs === undefined ? map.ingcs() : gcs));
if (!poly.outer) {
poly = {outer: poly, inner: []};
}
Expand All @@ -295,7 +300,7 @@ var lineFeature = function (arg) {
}
opts = opts || {};
opts.partial = opts.partial || false;
poly = {outer: transform.transformCoordinates(map.ingcs(), map.gcs(), poly.outer), inner: (poly.inner || []).map(inner => transform.transformCoordinates(map.ingcs(), map.gcs(), inner))};
poly = {outer: transform.transformCoordinates(gcs, map.gcs(), poly.outer), inner: (poly.inner || []).map(inner => transform.transformCoordinates(gcs, map.gcs(), inner))};
poly.outer.forEach(p => {
if (!min) {
min = {x: p.x, y: p.y};
Expand Down
21 changes: 13 additions & 8 deletions src/markerFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,13 @@ var markerFeature = function (arg) {
/**
* Returns an array of datum indices that contain the given marker.
*
* @param {geo.geoPosition} p marker to search for in map interface gcs.
* @param {geo.geoPosition} p marker to search for.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of marker indices, and
* `found`: a list of markers that contain the specified coordinate.
*/
this.pointSearch = function (p) {
this.pointSearch = function (p, gcs) {
var min, max, data, idx = [], found = [], ifound = [],
fgcs = m_this.gcs(), // this feature's gcs
corners,
Expand All @@ -186,8 +188,9 @@ var markerFeature = function (arg) {
// determined then
m_this._updateRangeTree();

var map = m_this.layer().map(),
pt = map.gcsToDisplay(p),
var map = m_this.layer().map();
gcs = (gcs === null ? map.gcs() : (gcs === undefined ? map.ingcs() : gcs));
var pt = map.gcsToDisplay(p, gcs),
zoom = map.zoom(),
zoomFactor = Math.pow(2, zoom),
maxr = this._approximateMaxRadius(zoom);
Expand Down Expand Up @@ -259,21 +262,22 @@ var markerFeature = function (arg) {
* This does not take clustering into account.
*
* @param {geo.polygonObject} poly A polygon as an array of coordinates or an
* object with `outer` and optionally `inner` parameters. All coordinates
* are in map interface gcs.
* object with `outer` and optionally `inner` parameters.
* @param {object} [opts] Additional search options.
* @param {boolean} [opts.partial=false] If truthy, include markers that are
* partially in the polygon, otherwise only include markers that are fully
* within the region. If 'center', only markers whose centers are inside
* the polygon are returned.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of marker indices,
* `found`: a list of markers within the polygon, and `extra`: an object
* with index keys containing an object with a `partial` key and a boolean
* value to indicate if the marker is on the polygon's border and a
* `distance` key to indicate how far within the polygon the marker is
* located.
*/
this.polygonSearch = function (poly, opts) {
this.polygonSearch = function (poly, opts, gcs) {
var fgcs = m_this.gcs(), // this feature's gcs
found = [],
ifound = [],
Expand All @@ -289,6 +293,7 @@ var markerFeature = function (arg) {
zoomFactor = Math.pow(2, zoom),
maxr = this._approximateMaxRadius(zoom);

gcs = (gcs === null ? map.gcs() : (gcs === undefined ? map.ingcs() : gcs));
if (!poly.outer) {
poly = {outer: poly, inner: []};
}
Expand All @@ -301,7 +306,7 @@ var markerFeature = function (arg) {
}
opts = opts || {};
opts.partial = opts.partial || false;
poly = {outer: map.gcsToDisplay(poly.outer), inner: (poly.inner || []).map(inner => map.gcsToDisplay(inner))};
poly = {outer: map.gcsToDisplay(poly.outer, gcs), inner: (poly.inner || []).map(inner => map.gcsToDisplay(inner, gcs))};
poly.outer.forEach(p => {
if (!min) {
min = {x: p.x, y: p.y};
Expand Down
8 changes: 5 additions & 3 deletions src/pixelmapFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,15 @@ var pixelmapFeature = function (arg) {
* information from the quad to determine the pixelmap index value so that it
* can be included in the `found` results.
*
* @param {geo.geoPosition} geo Coordinate in interface gcs.
* @param {geo.geoPosition} geo Coordinate.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {geo.feature.searchResult} An object with a list of features and
* feature indices that are located at the specified point.
*/
this.pointSearch = function (geo) {
this.pointSearch = function (geo, gcs) {
if (m_quadFeature && m_info) {
var result = m_quadFeature.pointSearch(geo);
var result = m_quadFeature.pointSearch(geo, gcs);
if (result.index.length === 1 && result.extra && result.extra[result.index[0]].basis) {
var basis = result.extra[result.index[0]].basis, x, y, idx;
x = Math.floor(basis.x * m_info.width);
Expand Down
17 changes: 10 additions & 7 deletions src/pointFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,13 @@ var pointFeature = function (arg) {
* https://github.com/dotskapes/wigglemaps/blob/cf5bed3fbfe2c3e48d31799462a80c564be1fb60/src/query/PointQuerier.js
* This does not take into account clustering.
*
* @param {geo.geoPosition} p point to search for in map interface gcs.
* @param {geo.geoPosition} p point to search for.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of point indices, and
* `found`: a list of points that contain the specified coordinate.
*/
this.pointSearch = function (p) {
this.pointSearch = function (p, gcs) {
var min, max, data, idx = [], found = [], ifound = [], map, pt,
fgcs = m_this.gcs(), // this feature's gcs
corners,
Expand All @@ -302,7 +304,7 @@ var pointFeature = function (arg) {
m_this._updateRangeTree();

map = m_this.layer().map();
pt = map.gcsToDisplay(p);
pt = map.gcsToDisplay(p, gcs);
// check all corners to make sure we handle rotations
corners = [
map.displayToGcs({x: pt.x - m_maxRadius, y: pt.y - m_maxRadius}, fgcs),
Expand Down Expand Up @@ -357,21 +359,22 @@ var pointFeature = function (arg) {
* This does not take clustering into account.
*
* @param {geo.polygonObject} poly A polygon as an array of coordinates or an
* object with `outer` and optionally `inner` parameters. All coordinates
* are in map interface gcs.
* object with `outer` and optionally `inner` parameters.
* @param {object} [opts] Additional search options.
* @param {boolean} [opts.partial=false] If truthy, include points that are
* partially in the polygon, otherwise only include points that are fully
* within the region. If 'center', only points whose centers are inside
* the polygon are returned.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of point indices,
* `found`: a list of points within the polygon, and `extra`: an object
* with index keys containing an object with a `partial` key and a boolean
* value to indicate if the point is on the polygon's border and a
* `distance` key to indicate how far within the polygon the point is
* located.
*/
this.polygonSearch = function (poly, opts) {
this.polygonSearch = function (poly, opts, gcs) {
var fgcs = m_this.gcs(), // this feature's gcs
found = [],
ifound = [],
Expand All @@ -395,7 +398,7 @@ var pointFeature = function (arg) {
}
opts = opts || {};
opts.partial = opts.partial || false;
poly = {outer: map.gcsToDisplay(poly.outer), inner: (poly.inner || []).map(inner => map.gcsToDisplay(inner))};
poly = {outer: map.gcsToDisplay(poly.outer, gcs), inner: (poly.inner || []).map(inner => map.gcsToDisplay(inner, gcs))};
poly.outer.forEach(p => {
if (!min) {
min = {x: p.x, y: p.y};
Expand Down
22 changes: 13 additions & 9 deletions src/polygonFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,15 +260,17 @@ var polygonFeature = function (arg) {
* Point search method for selection api. Returns markers containing the
* given point.
*
* @param {geo.geoPosition} coordinate point to search for in map interface
* gcs.
* @param {geo.geoPosition} coordinate point to search for.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of polygon indices, and
* `found`: a list of polygons that contain the specified coordinate.
*/
this.pointSearch = function (coordinate) {
this.pointSearch = function (coordinate, gcs) {
var found = [], indices = [], irecord = {}, data = m_this.data(),
map = m_this.layer().map(),
pt = transform.transformCoordinates(map.ingcs(), map.gcs(), coordinate);
map = m_this.layer().map();
gcs = (gcs === null ? map.gcs() : (gcs === undefined ? map.ingcs() : gcs));
var pt = transform.transformCoordinates(gcs, map.gcs(), coordinate);
m_coordinates.forEach(function (coord, i) {
var inside = util.pointInPolygon(
pt,
Expand Down Expand Up @@ -304,21 +306,23 @@ var polygonFeature = function (arg) {
* specified polygon and whose vertices are not near the selected polygon.
*
* @param {geo.polygonObject} poly A polygon as an array of coordinates or an
* object with `outer` and optionally `inner` parameters. All coordinates
* are in map interface gcs.
* object with `outer` and optionally `inner` parameters.
* @param {object} [opts] Additional search options.
* @param {boolean} [opts.partial=false] If truthy, include polygons that are
* partially in the polygon, otherwise only include polygons that are fully
* within the region.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of polygon indices,
* `found`: a list of polygons within the polygon, and `extra`: an object
* with index keys containing an object with a `partial` key and a boolean
* value to indicate if the polygon is on the specified polygon's border.
*/
this.polygonSearch = function (poly, opts) {
this.polygonSearch = function (poly, opts, gcs) {
var data = m_this.data(), indices = [], found = [], extra = {}, min, max,
origPoly = poly, irecord = {},
map = m_this.layer().map();
gcs = (gcs === null ? map.gcs() : (gcs === undefined ? map.ingcs() : gcs));
if (!poly.outer) {
poly = {outer: poly, inner: []};
}
Expand All @@ -331,7 +335,7 @@ var polygonFeature = function (arg) {
}
opts = opts || {};
opts.partial = opts.partial || false;
poly = {outer: transform.transformCoordinates(map.ingcs(), map.gcs(), poly.outer), inner: (poly.inner || []).map(inner => transform.transformCoordinates(map.ingcs(), map.gcs(), inner))};
poly = {outer: transform.transformCoordinates(gcs, map.gcs(), poly.outer), inner: (poly.inner || []).map(inner => transform.transformCoordinates(gcs, map.gcs(), inner))};
poly.outer.forEach(p => {
if (!min) {
min = {x: p.x, y: p.y};
Expand Down
9 changes: 6 additions & 3 deletions src/quadFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,21 +154,24 @@ var quadFeature = function (arg) {
* given point.
*
* @param {geo.geoPosition} coordinate Coordinate in input gcs to check if it
* is located in any quad in map interface gcs.
* is located in any quad.
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
* the interface gcs, `null` to use the map gcs, or any other transform.
* @returns {object} An object with `index`: a list of quad indices, `found`:
* a list of quads that contain the specified coordinate, and `extra`: an
* object with keys that are quad indices and values that are objects with
* `basis.x` and `basis.y`, values from 0 - 1 relative to interior of the
* quad.
*/
this.pointSearch = function (coordinate) {
this.pointSearch = function (coordinate, gcs) {
var found = [], indices = [], extra = {},
poly1 = [{}, {}, {}, {}], poly2 = [{}, {}, {}, {}],
order1 = [0, 1, 2, 0], order2 = [1, 2, 3, 1],
data = m_this.data(),
map = m_this.layer().map(),
i, coordbasis;
coordinate = transform.transformCoordinates(map.ingcs(), map.gcs(), coordinate);
gcs = (gcs === null ? map.gcs() : (gcs === undefined ? map.ingcs() : gcs));
coordinate = transform.transformCoordinates(gcs, map.gcs(), coordinate);
if (!m_quads) {
m_this._generateQuads();
}
Expand Down