use static classes for docsets instead of inner classes to make sure we don't rely on hotspot to inline field lookups
This commit is contained in:
parent
451c87f486
commit
55f62eca8a
|
@ -66,79 +66,103 @@ public class GeoBoundingBoxFilter extends Filter {
|
||||||
|
|
||||||
//checks to see if bounding box crosses 180 degrees
|
//checks to see if bounding box crosses 180 degrees
|
||||||
if (topLeft.lon > bottomRight.lon) {
|
if (topLeft.lon > bottomRight.lon) {
|
||||||
return new GetDocSet(reader.maxDoc()) {
|
return new LeftGeoBoundingBoxDocSet(reader.maxDoc(), fieldData, topLeft, bottomRight);
|
||||||
|
|
||||||
@Override public boolean isCacheable() {
|
|
||||||
// not cacheable for several reasons:
|
|
||||||
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
|
||||||
// 2. Its already fast without in mem bitset, since it works with field data
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean get(int doc) throws IOException {
|
|
||||||
if (!fieldData.hasValue(doc)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldData.multiValued()) {
|
|
||||||
double[] lats = fieldData.latValues(doc);
|
|
||||||
double[] lons = fieldData.lonValues(doc);
|
|
||||||
for (int i = 0; i < lats.length; i++) {
|
|
||||||
double lat = lats[i];
|
|
||||||
double lon = lons[i];
|
|
||||||
if (((topLeft.lon <= lon && 180 >= lon) || (-180 <= lon && bottomRight.lon >= lon)) &&
|
|
||||||
(topLeft.lat >= lat && bottomRight.lat <= lat)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
double lat = fieldData.latValue(doc);
|
|
||||||
double lon = fieldData.lonValue(doc);
|
|
||||||
|
|
||||||
if (((topLeft.lon <= lon && 180 >= lon) || (-180 <= lon && bottomRight.lon >= lon)) &&
|
|
||||||
(topLeft.lat >= lat && bottomRight.lat <= lat)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
return new GetDocSet(reader.maxDoc()) {
|
return new RightGeoBoundingBoxDocSet(reader.maxDoc(), fieldData, topLeft, bottomRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override public boolean isCacheable() {
|
public static class LeftGeoBoundingBoxDocSet extends GetDocSet {
|
||||||
// not cacheable for several reasons:
|
private final GeoPointFieldData fieldData;
|
||||||
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
private final Point topLeft;
|
||||||
// 2. Its already fast without in mem bitset, since it works with field data
|
private final Point bottomRight;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean get(int doc) throws IOException {
|
public LeftGeoBoundingBoxDocSet(int maxDoc, GeoPointFieldData fieldData, Point topLeft, Point bottomRight) {
|
||||||
if (!fieldData.hasValue(doc)) {
|
super(maxDoc);
|
||||||
return false;
|
this.fieldData = fieldData;
|
||||||
|
this.topLeft = topLeft;
|
||||||
|
this.bottomRight = bottomRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isCacheable() {
|
||||||
|
// not cacheable for several reasons:
|
||||||
|
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
||||||
|
// 2. Its already fast without in mem bitset, since it works with field data
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean get(int doc) throws IOException {
|
||||||
|
if (!fieldData.hasValue(doc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldData.multiValued()) {
|
||||||
|
double[] lats = fieldData.latValues(doc);
|
||||||
|
double[] lons = fieldData.lonValues(doc);
|
||||||
|
for (int i = 0; i < lats.length; i++) {
|
||||||
|
double lat = lats[i];
|
||||||
|
double lon = lons[i];
|
||||||
|
if (((topLeft.lon <= lon && 180 >= lon) || (-180 <= lon && bottomRight.lon >= lon)) &&
|
||||||
|
(topLeft.lat >= lat && bottomRight.lat <= lat)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldData.multiValued()) {
|
|
||||||
double[] lats = fieldData.latValues(doc);
|
|
||||||
double[] lons = fieldData.lonValues(doc);
|
|
||||||
for (int i = 0; i < lats.length; i++) {
|
|
||||||
if (topLeft.lon <= lons[i] && bottomRight.lon >= lons[i]
|
|
||||||
&& topLeft.lat >= lats[i] && bottomRight.lat <= lats[i]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
double lat = fieldData.latValue(doc);
|
|
||||||
double lon = fieldData.lonValue(doc);
|
|
||||||
|
|
||||||
if (topLeft.lon <= lon && bottomRight.lon >= lon
|
|
||||||
&& topLeft.lat >= lat && bottomRight.lat <= lat) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
};
|
} else {
|
||||||
|
double lat = fieldData.latValue(doc);
|
||||||
|
double lon = fieldData.lonValue(doc);
|
||||||
|
|
||||||
|
if (((topLeft.lon <= lon && 180 >= lon) || (-180 <= lon && bottomRight.lon >= lon)) &&
|
||||||
|
(topLeft.lat >= lat && bottomRight.lat <= lat)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RightGeoBoundingBoxDocSet extends GetDocSet {
|
||||||
|
private final GeoPointFieldData fieldData;
|
||||||
|
private final Point topLeft;
|
||||||
|
private final Point bottomRight;
|
||||||
|
|
||||||
|
public RightGeoBoundingBoxDocSet(int maxDoc, GeoPointFieldData fieldData, Point topLeft, Point bottomRight) {
|
||||||
|
super(maxDoc);
|
||||||
|
this.fieldData = fieldData;
|
||||||
|
this.topLeft = topLeft;
|
||||||
|
this.bottomRight = bottomRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isCacheable() {
|
||||||
|
// not cacheable for several reasons:
|
||||||
|
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
||||||
|
// 2. Its already fast without in mem bitset, since it works with field data
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean get(int doc) throws IOException {
|
||||||
|
if (!fieldData.hasValue(doc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldData.multiValued()) {
|
||||||
|
double[] lats = fieldData.latValues(doc);
|
||||||
|
double[] lons = fieldData.lonValues(doc);
|
||||||
|
for (int i = 0; i < lats.length; i++) {
|
||||||
|
if (topLeft.lon <= lons[i] && bottomRight.lon >= lons[i]
|
||||||
|
&& topLeft.lat >= lats[i] && bottomRight.lat <= lats[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
double lat = fieldData.latValue(doc);
|
||||||
|
double lon = fieldData.lonValue(doc);
|
||||||
|
|
||||||
|
if (topLeft.lon <= lon && bottomRight.lon >= lon
|
||||||
|
&& topLeft.lat >= lat && bottomRight.lat <= lat) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,36 +78,7 @@ public class GeoDistanceFilter extends Filter {
|
||||||
|
|
||||||
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
|
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
|
||||||
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
|
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
|
||||||
return new GetDocSet(reader.maxDoc()) {
|
return new GeoDistanceDocSet(reader.maxDoc(), geoDistance, fieldData, lat, lon, distance);
|
||||||
|
|
||||||
@Override public boolean isCacheable() {
|
|
||||||
// not cacheable for several reasons:
|
|
||||||
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
|
||||||
// 2. Its already fast without in mem bitset, since it works with field data
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean get(int doc) throws IOException {
|
|
||||||
if (!fieldData.hasValue(doc)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldData.multiValued()) {
|
|
||||||
double[] lats = fieldData.latValues(doc);
|
|
||||||
double[] lons = fieldData.lonValues(doc);
|
|
||||||
for (int i = 0; i < lats.length; i++) {
|
|
||||||
double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES);
|
|
||||||
if (d < distance) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES);
|
|
||||||
return d < distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -140,4 +111,49 @@ public class GeoDistanceFilter extends Filter {
|
||||||
result = 31 * result + (fieldName != null ? fieldName.hashCode() : 0);
|
result = 31 * result + (fieldName != null ? fieldName.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class GeoDistanceDocSet extends GetDocSet {
|
||||||
|
private final GeoDistance geoDistance;
|
||||||
|
private final GeoPointFieldData fieldData;
|
||||||
|
private final double lat;
|
||||||
|
private final double lon;
|
||||||
|
private final double distance;
|
||||||
|
|
||||||
|
public GeoDistanceDocSet(int maxDoc, GeoDistance geoDistance, GeoPointFieldData fieldData, double lat, double lon, double distance) {
|
||||||
|
super(maxDoc);
|
||||||
|
this.geoDistance = geoDistance;
|
||||||
|
this.fieldData = fieldData;
|
||||||
|
this.lat = lat;
|
||||||
|
this.lon = lon;
|
||||||
|
this.distance = distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isCacheable() {
|
||||||
|
// not cacheable for several reasons:
|
||||||
|
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
||||||
|
// 2. Its already fast without in mem bitset, since it works with field data
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean get(int doc) throws IOException {
|
||||||
|
if (!fieldData.hasValue(doc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldData.multiValued()) {
|
||||||
|
double[] lats = fieldData.latValues(doc);
|
||||||
|
double[] lons = fieldData.lonValues(doc);
|
||||||
|
for (int i = 0; i < lats.length; i++) {
|
||||||
|
double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES);
|
||||||
|
if (d < distance) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES);
|
||||||
|
return d < distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ import java.io.IOException;
|
||||||
public class GeoDistanceRangeFilter extends Filter {
|
public class GeoDistanceRangeFilter extends Filter {
|
||||||
|
|
||||||
private final double lat;
|
private final double lat;
|
||||||
|
|
||||||
private final double lon;
|
private final double lon;
|
||||||
|
|
||||||
private final double inclusiveLowerPoint; // in miles
|
private final double inclusiveLowerPoint; // in miles
|
||||||
|
@ -90,39 +89,7 @@ public class GeoDistanceRangeFilter extends Filter {
|
||||||
|
|
||||||
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
|
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
|
||||||
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
|
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
|
||||||
return new GetDocSet(reader.maxDoc()) {
|
return new GeoDistanceRangeDocSet(reader.maxDoc(), fieldData, geoDistance, lat, lon, inclusiveLowerPoint, inclusiveUpperPoint);
|
||||||
|
|
||||||
@Override public boolean isCacheable() {
|
|
||||||
// not cacheable for several reasons:
|
|
||||||
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
|
||||||
// 2. Its already fast without in mem bitset, since it works with field data
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean get(int doc) throws IOException {
|
|
||||||
if (!fieldData.hasValue(doc)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldData.multiValued()) {
|
|
||||||
double[] lats = fieldData.latValues(doc);
|
|
||||||
double[] lons = fieldData.lonValues(doc);
|
|
||||||
for (int i = 0; i < lats.length; i++) {
|
|
||||||
double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES);
|
|
||||||
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES);
|
|
||||||
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -158,4 +125,55 @@ public class GeoDistanceRangeFilter extends Filter {
|
||||||
result = 31 * result + (fieldName != null ? fieldName.hashCode() : 0);
|
result = 31 * result + (fieldName != null ? fieldName.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class GeoDistanceRangeDocSet extends GetDocSet {
|
||||||
|
|
||||||
|
private final GeoPointFieldData fieldData;
|
||||||
|
private final GeoDistance geoDistance;
|
||||||
|
private final double lat;
|
||||||
|
private final double lon;
|
||||||
|
private final double inclusiveLowerPoint; // in miles
|
||||||
|
private final double inclusiveUpperPoint; // in miles
|
||||||
|
|
||||||
|
public GeoDistanceRangeDocSet(int maxDoc, GeoPointFieldData fieldData, GeoDistance geoDistance, double lat, double lon, double inclusiveLowerPoint, double inclusiveUpperPoint) {
|
||||||
|
super(maxDoc);
|
||||||
|
this.fieldData = fieldData;
|
||||||
|
this.geoDistance = geoDistance;
|
||||||
|
this.lat = lat;
|
||||||
|
this.lon = lon;
|
||||||
|
this.inclusiveLowerPoint = inclusiveLowerPoint;
|
||||||
|
this.inclusiveUpperPoint = inclusiveUpperPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean isCacheable() {
|
||||||
|
// not cacheable for several reasons:
|
||||||
|
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
||||||
|
// 2. Its already fast without in mem bitset, since it works with field data
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean get(int doc) throws IOException {
|
||||||
|
if (!fieldData.hasValue(doc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldData.multiValued()) {
|
||||||
|
double[] lats = fieldData.latValues(doc);
|
||||||
|
double[] lons = fieldData.lonValues(doc);
|
||||||
|
for (int i = 0; i < lats.length; i++) {
|
||||||
|
double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES);
|
||||||
|
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES);
|
||||||
|
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,55 +56,64 @@ public class GeoPolygonFilter extends Filter {
|
||||||
|
|
||||||
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
|
@Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
|
||||||
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
|
final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName);
|
||||||
|
return new GeoPolygonDocSet(reader.maxDoc(), fieldData, points);
|
||||||
return new GetDocSet(reader.maxDoc()) {
|
|
||||||
|
|
||||||
@Override public boolean isCacheable() {
|
|
||||||
// not cacheable for several reasons:
|
|
||||||
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
|
||||||
// 2. Its already fast without in mem bitset, since it works with field data
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean get(int doc) throws IOException {
|
|
||||||
if (!fieldData.hasValue(doc)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldData.multiValued()) {
|
|
||||||
double[] lats = fieldData.latValues(doc);
|
|
||||||
double[] lons = fieldData.lonValues(doc);
|
|
||||||
for (int i = 0; i < lats.length; i++) {
|
|
||||||
if (pointInPolygon(points, lats[i], lons[i])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
double lat = fieldData.latValue(doc);
|
|
||||||
double lon = fieldData.lonValue(doc);
|
|
||||||
return pointInPolygon(points, lat, lon);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean pointInPolygon(Point[] points, double lat, double lon) {
|
public static class GeoPolygonDocSet extends GetDocSet {
|
||||||
int i;
|
private final GeoPointFieldData fieldData;
|
||||||
int j = points.length - 1;
|
private final Point[] points;
|
||||||
boolean inPoly = false;
|
|
||||||
|
|
||||||
for (i = 0; i < points.length; i++) {
|
public GeoPolygonDocSet(int maxDoc, GeoPointFieldData fieldData, Point[] points) {
|
||||||
if (points[i].lon < lon && points[j].lon >= lon
|
super(maxDoc);
|
||||||
|| points[j].lon < lon && points[i].lon >= lon) {
|
this.fieldData = fieldData;
|
||||||
if (points[i].lat + (lon - points[i].lon) /
|
this.points = points;
|
||||||
(points[j].lon - points[i].lon) * (points[j].lat - points[i].lat) < lat) {
|
}
|
||||||
inPoly = !inPoly;
|
|
||||||
}
|
@Override public boolean isCacheable() {
|
||||||
}
|
// not cacheable for several reasons:
|
||||||
j = i;
|
// 1. It is only relevant when _cache is set to true, and then, we really want to create in mem bitset
|
||||||
|
// 2. Its already fast without in mem bitset, since it works with field data
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean get(int doc) throws IOException {
|
||||||
|
if (!fieldData.hasValue(doc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldData.multiValued()) {
|
||||||
|
double[] lats = fieldData.latValues(doc);
|
||||||
|
double[] lons = fieldData.lonValues(doc);
|
||||||
|
for (int i = 0; i < lats.length; i++) {
|
||||||
|
if (pointInPolygon(points, lats[i], lons[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
double lat = fieldData.latValue(doc);
|
||||||
|
double lon = fieldData.lonValue(doc);
|
||||||
|
return pointInPolygon(points, lat, lon);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean pointInPolygon(Point[] points, double lat, double lon) {
|
||||||
|
int i;
|
||||||
|
int j = points.length - 1;
|
||||||
|
boolean inPoly = false;
|
||||||
|
|
||||||
|
for (i = 0; i < points.length; i++) {
|
||||||
|
if (points[i].lon < lon && points[j].lon >= lon
|
||||||
|
|| points[j].lon < lon && points[i].lon >= lon) {
|
||||||
|
if (points[i].lat + (lon - points[i].lon) /
|
||||||
|
(points[j].lon - points[i].lon) * (points[j].lat - points[i].lat) < lat) {
|
||||||
|
inPoly = !inPoly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
return inPoly;
|
||||||
}
|
}
|
||||||
return inPoly;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Point {
|
public static class Point {
|
||||||
|
|
Loading…
Reference in New Issue