diff --git a/pom.xml b/pom.xml index 47989386f7c..ced122f036d 100644 --- a/pom.xml +++ b/pom.xml @@ -157,6 +157,7 @@ spatial4j 0.2 compile + true @@ -164,6 +165,7 @@ jts 1.12 compile + true xerces diff --git a/src/main/java/org/elasticsearch/common/geo/GeoJSONShapeParser.java b/src/main/java/org/elasticsearch/common/geo/GeoJSONShapeParser.java index 484a6c76fa2..7dafbfdbad7 100644 --- a/src/main/java/org/elasticsearch/common/geo/GeoJSONShapeParser.java +++ b/src/main/java/org/elasticsearch/common/geo/GeoJSONShapeParser.java @@ -1,10 +1,31 @@ +/* + * Licensed to ElasticSearch and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. ElasticSearch licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.elasticsearch.common.geo; import com.spatial4j.core.shape.Shape; import com.spatial4j.core.shape.jts.JtsGeometry; import com.spatial4j.core.shape.jts.JtsPoint; import com.spatial4j.core.shape.simple.RectangleImpl; -import com.vividsolutions.jts.geom.*; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LinearRing; import org.elasticsearch.ElasticSearchParseException; import org.elasticsearch.common.xcontent.XContentParser; @@ -16,17 +37,17 @@ import java.util.Locale; /** * Parsers which supports reading {@link Shape}s in GeoJSON format from a given * {@link XContentParser}. - * + *

* An example of the format used for polygons: - * + *

* { - * "type": "Polygon", - * "coordinates": [ - * [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], - * [100.0, 1.0], [100.0, 0.0] ] - * ] + * "type": "Polygon", + * "coordinates": [ + * [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], + * [100.0, 1.0], [100.0, 0.0] ] + * ] * } - * + *

* Note, currently MultiPolygon and GeometryCollections are not supported */ public class GeoJSONShapeParser { @@ -112,7 +133,7 @@ public class GeoJSONShapeParser { * of coordinates * * @param shapeType Type of Shape to be built - * @param node Root node of the coordinate tree + * @param node Root node of the coordinate tree * @return Shape built from the coordinates */ private static Shape buildShape(String shapeType, CoordinateNode node) { @@ -157,7 +178,7 @@ public class GeoJSONShapeParser { /** * Node used to represent a tree of coordinates. - * + *

* Can either be a leaf node consisting of a Coordinate, or a parent with children */ private static class CoordinateNode { diff --git a/src/main/java/org/elasticsearch/common/geo/GeoJSONShapeSerializer.java b/src/main/java/org/elasticsearch/common/geo/GeoJSONShapeSerializer.java index c20ddde60a6..34843da22b5 100644 --- a/src/main/java/org/elasticsearch/common/geo/GeoJSONShapeSerializer.java +++ b/src/main/java/org/elasticsearch/common/geo/GeoJSONShapeSerializer.java @@ -1,9 +1,28 @@ +/* + * Licensed to ElasticSearch and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. ElasticSearch licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.elasticsearch.common.geo; -import com.spatial4j.core.shape.*; +import com.spatial4j.core.shape.Rectangle; +import com.spatial4j.core.shape.Shape; import com.spatial4j.core.shape.jts.JtsGeometry; import com.vividsolutions.jts.geom.*; -import com.vividsolutions.jts.geom.Point; import org.elasticsearch.ElasticSearchIllegalArgumentException; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -11,9 +30,9 @@ import java.io.IOException; /** * Serializes {@link Shape} instances into GeoJSON format - * + *

* Example of the format used for points: - * + *

* { "type": "Point", "coordinates": [100.0, 0.0] } */ public class GeoJSONShapeSerializer { @@ -25,7 +44,7 @@ public class GeoJSONShapeSerializer { * Serializes the given {@link Shape} as GeoJSON format into the given * {@link XContentBuilder} * - * @param shape Shape that will be serialized + * @param shape Shape that will be serialized * @param builder XContentBuilder it will be serialized to * @throws IOException Thrown if an error occurs while writing to the XContentBuilder */ @@ -56,7 +75,7 @@ public class GeoJSONShapeSerializer { * Serializes the given {@link Rectangle} * * @param rectangle Rectangle that will be serialized - * @param builder XContentBuilder it will be serialized to + * @param builder XContentBuilder it will be serialized to * @throws IOException Thrown if an error occurs while writing to the XContentBuilder */ private static void serializeRectangle(Rectangle rectangle, XContentBuilder builder) throws IOException { @@ -70,7 +89,7 @@ public class GeoJSONShapeSerializer { /** * Serializes the given {@link Point} * - * @param point Point that will be serialized + * @param point Point that will be serialized * @param builder XContentBuilder it will be serialized to * @throws IOException Thrown if an error occurs while writing to the XContentBuilder */ @@ -84,7 +103,7 @@ public class GeoJSONShapeSerializer { /** * Serializes the given {@link com.spatial4j.core.shape.Point} * - * @param point Point that will be serialized + * @param point Point that will be serialized * @param builder XContentBuilder it will be serialized to * @throws IOException Thrown if an error occurs while writing to the XContentBuilder */ @@ -99,7 +118,7 @@ public class GeoJSONShapeSerializer { * Serializes the given {@link LineString} * * @param lineString LineString that will be serialized - * @param builder XContentBuilder it will be serialized to + * @param builder XContentBuilder it will be serialized to * @throws IOException Thrown if an error occurs while writing to the XContentBuilder */ private static void serializeLineString(LineString lineString, XContentBuilder builder) throws IOException { @@ -152,7 +171,7 @@ public class GeoJSONShapeSerializer { * Serializes the given {@link MultiPoint} * * @param multiPoint MulitPoint that will be serialized - * @param builder XContentBuilder it will be serialized to + * @param builder XContentBuilder it will be serialized to * @throws IOException Thrown if an error occurs while writing to the XContentBuilder */ private static void serializeMultiPoint(MultiPoint multiPoint, XContentBuilder builder) throws IOException { @@ -170,7 +189,7 @@ public class GeoJSONShapeSerializer { * Serializes the given {@link Coordinate} * * @param coordinate Coordinate that will be serialized - * @param builder XContentBuilder it will be serialized to + * @param builder XContentBuilder it will be serialized to * @throws IOException Thrown if an error occurs while writing to the XContentBuilder */ private static void serializeCoordinate(Coordinate coordinate, XContentBuilder builder) throws IOException { diff --git a/src/main/java/org/elasticsearch/common/geo/ShapeBuilder.java b/src/main/java/org/elasticsearch/common/geo/ShapeBuilder.java index fa573612061..256dc8ef274 100644 --- a/src/main/java/org/elasticsearch/common/geo/ShapeBuilder.java +++ b/src/main/java/org/elasticsearch/common/geo/ShapeBuilder.java @@ -1,3 +1,22 @@ +/* + * Licensed to ElasticSearch and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. ElasticSearch licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.elasticsearch.common.geo; import com.spatial4j.core.shape.Point; @@ -88,7 +107,7 @@ public class ShapeBuilder { * Builder for creating a {@link Rectangle} instance */ public static class RectangleBuilder { - + private Point topLeft; private Point bottomRight; diff --git a/src/main/java/org/elasticsearch/common/geo/ShapeRelation.java b/src/main/java/org/elasticsearch/common/geo/ShapeRelation.java index 1aaeb4f1d70..5402e161cfe 100644 --- a/src/main/java/org/elasticsearch/common/geo/ShapeRelation.java +++ b/src/main/java/org/elasticsearch/common/geo/ShapeRelation.java @@ -1,3 +1,22 @@ +/* + * Licensed to ElasticSearch and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. ElasticSearch licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.elasticsearch.common.geo; import java.util.Locale; diff --git a/src/main/java/org/elasticsearch/common/geo/ShapesAvailability.java b/src/main/java/org/elasticsearch/common/geo/ShapesAvailability.java new file mode 100644 index 00000000000..bef043d5d77 --- /dev/null +++ b/src/main/java/org/elasticsearch/common/geo/ShapesAvailability.java @@ -0,0 +1,56 @@ +/* + * Licensed to ElasticSearch and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. ElasticSearch licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.common.geo; + +import com.spatial4j.core.shape.simple.PointImpl; +import com.vividsolutions.jts.geom.GeometryFactory; + +/** + */ +public class ShapesAvailability { + + public static final boolean SPATIAL4J_AVAILABLE; + public static final boolean JTS_AVAILABLE; + + static { + boolean xSPATIAL4J_AVAILABLE; + try { + new PointImpl(0, 0); + xSPATIAL4J_AVAILABLE = true; + } catch (Throwable t) { + xSPATIAL4J_AVAILABLE = false; + } + SPATIAL4J_AVAILABLE = xSPATIAL4J_AVAILABLE; + + boolean xJTS_AVAILABLE; + try { + new GeometryFactory(); + xJTS_AVAILABLE = true; + } catch (Throwable t) { + xJTS_AVAILABLE = false; + } + JTS_AVAILABLE = xJTS_AVAILABLE; + } + + + private ShapesAvailability() { + + } +} diff --git a/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java b/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java index 6b303c320f2..40f71714cdc 100644 --- a/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java +++ b/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.collect.Tuple; +import org.elasticsearch.common.geo.ShapesAvailability; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentFactory; @@ -70,7 +71,7 @@ public class DocumentMapperParser extends AbstractIndexComponent { public DocumentMapperParser(Index index, @IndexSettings Settings indexSettings, AnalysisService analysisService) { super(index, indexSettings); this.analysisService = analysisService; - typeParsers = new MapBuilder() + MapBuilder typeParsersBuilder = new MapBuilder() .put(ByteFieldMapper.CONTENT_TYPE, new ByteFieldMapper.TypeParser()) .put(ShortFieldMapper.CONTENT_TYPE, new ShortFieldMapper.TypeParser()) .put(IntegerFieldMapper.CONTENT_TYPE, new IntegerFieldMapper.TypeParser()) @@ -85,9 +86,13 @@ public class DocumentMapperParser extends AbstractIndexComponent { .put(ObjectMapper.CONTENT_TYPE, new ObjectMapper.TypeParser()) .put(ObjectMapper.NESTED_CONTENT_TYPE, new ObjectMapper.TypeParser()) .put(MultiFieldMapper.CONTENT_TYPE, new MultiFieldMapper.TypeParser()) - .put(GeoPointFieldMapper.CONTENT_TYPE, new GeoPointFieldMapper.TypeParser()) - .put(GeoShapeFieldMapper.CONTENT_TYPE, new GeoShapeFieldMapper.TypeParser()) - .immutableMap(); + .put(GeoPointFieldMapper.CONTENT_TYPE, new GeoPointFieldMapper.TypeParser()); + + if (ShapesAvailability.JTS_AVAILABLE) { + typeParsersBuilder.put(GeoShapeFieldMapper.CONTENT_TYPE, new GeoShapeFieldMapper.TypeParser()); + } + + typeParsers = typeParsersBuilder.immutableMap(); rootTypeParsers = new MapBuilder() .put(SizeFieldMapper.NAME, new SizeFieldMapper.TypeParser()) diff --git a/src/main/java/org/elasticsearch/indices/query/IndicesQueriesRegistry.java b/src/main/java/org/elasticsearch/indices/query/IndicesQueriesRegistry.java index 8dd0b4e4ee1..93c7013e3db 100644 --- a/src/main/java/org/elasticsearch/indices/query/IndicesQueriesRegistry.java +++ b/src/main/java/org/elasticsearch/indices/query/IndicesQueriesRegistry.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.geo.ShapesAvailability; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.query.*; @@ -74,7 +75,9 @@ public class IndicesQueriesRegistry { addQueryParser(queryParsers, new FuzzyLikeThisFieldQueryParser()); addQueryParser(queryParsers, new WrapperQueryParser()); addQueryParser(queryParsers, new IndicesQueryParser(clusterService)); - addQueryParser(queryParsers, new GeoShapeQueryParser()); + if (ShapesAvailability.JTS_AVAILABLE) { + addQueryParser(queryParsers, new GeoShapeQueryParser()); + } this.queryParsers = ImmutableMap.copyOf(queryParsers); Map filterParsers = Maps.newHashMap(); @@ -93,7 +96,9 @@ public class IndicesQueriesRegistry { addFilterParser(filterParsers, new GeoDistanceRangeFilterParser()); addFilterParser(filterParsers, new GeoBoundingBoxFilterParser()); addFilterParser(filterParsers, new GeoPolygonFilterParser()); - addFilterParser(filterParsers, new GeoShapeFilterParser()); + if (ShapesAvailability.JTS_AVAILABLE) { + addFilterParser(filterParsers, new GeoShapeFilterParser()); + } addFilterParser(filterParsers, new QueryFilterParser()); addFilterParser(filterParsers, new FQueryFilterParser()); addFilterParser(filterParsers, new BoolFilterParser());