From 06087f861064e39aca13d6e10131c873e97dd9fd Mon Sep 17 00:00:00 2001 From: Volker Mische Date: Fri, 10 Jun 2016 12:48:35 +0200 Subject: [PATCH] CBIDXT-253: Encode geometries as WKB (Well-Known Binary) The geometries were stored as Erlang terms on disk. This is bad for interoperability. The geometries are now stored as WKB (Well-Known Binary). This is a port of 59fa3590a43386d59f757604d99c8f051ea00752 to the Apache CouchDB compatible version for GeoCouch. Change-Id: I76b834461bd14b5ac684b6b4f52d3da8db8b8f95 --- gc-couchdb/src/couch_spatial_updater.erl | 34 +++--------------------- gc-couchdb/src/couch_spatial_util.erl | 16 +++-------- 2 files changed, 6 insertions(+), 44 deletions(-) diff --git a/gc-couchdb/src/couch_spatial_updater.erl b/gc-couchdb/src/couch_spatial_updater.erl index 6357e74..54b2b3a 100644 --- a/gc-couchdb/src/couch_spatial_updater.erl +++ b/gc-couchdb/src/couch_spatial_updater.erl @@ -18,11 +18,8 @@ -export([start_update/3, process_doc/3, finish_update/1]). -% for output (couch_http_spatial, couch_http_spatial_list) --export([geocouch_to_geojsongeom/1]). - % for polygon search --export([extract_bbox/2, geojsongeom_to_geocouch/1]). +-export([extract_bbox/2]). -include("couch_db.hrl"). -include("couch_spatial.hrl"). @@ -313,7 +310,7 @@ process_result([[{Geo}|Rest]|[Value]]) -> % The multidimensional case without a geometry process_result([MultiDim|[Value]]) when is_list(MultiDim) -> Tuples = process_range(MultiDim), - {Tuples, {nil, Value}}; + {Tuples, {<<>>, Value}}; % There old case when only two dimensions were supported process_result([{Geo}|[Value]]) -> {Bbox, Geom} = process_geometry(Geo), @@ -377,7 +374,7 @@ process_geometry(Geo) -> catch _:badarg -> throw({emit_key, <<"The supplied geometry must be valid GeoJSON.">>}) end, - Geom = geojsongeom_to_geocouch(Geo), + {ok, Geom} = wkb_writer:geojson_to_wkb({Geo}), {Bbox, Geom}. @@ -415,28 +412,3 @@ bbox([Coords|Rest], Range) -> {erlang:min(Coord, Min), erlang:max(Coord, Max)} end, Coords, Range), bbox(Rest, Range2). - - -% @doc Transforms a GeoJSON geometry (as Erlang terms), to an internal -% structure -geojsongeom_to_geocouch(Geom) -> - Type = proplists:get_value(<<"type">>, Geom), - Coords = case Type of - <<"GeometryCollection">> -> - Geometries = proplists:get_value(<<"geometries">>, Geom), - [geojsongeom_to_geocouch(G) || {G} <- Geometries]; - _ -> - proplists:get_value(<<"coordinates">>, Geom) - end, - {binary_to_atom(Type, utf8), Coords}. - -% @doc Transforms internal structure to a GeoJSON geometry (as Erlang terms) -geocouch_to_geojsongeom({Type, Coords}) -> - Coords2 = case Type of - 'GeometryCollection' -> - Geoms = [geocouch_to_geojsongeom(C) || C <- Coords], - {<<"geometries">>, Geoms}; - _ -> - {<<"coordinates">>, Coords} - end, - {[{<<"type">>, Type}, Coords2]}. diff --git a/gc-couchdb/src/couch_spatial_util.erl b/gc-couchdb/src/couch_spatial_util.erl index d3f3525..e635ec7 100644 --- a/gc-couchdb/src/couch_spatial_util.erl +++ b/gc-couchdb/src/couch_spatial_util.erl @@ -342,22 +342,12 @@ expand_dups([KV | Rest], Acc) -> row_to_ejson({Mbb, DocId, Geom, Value}) -> - % If there's no geometry in the output, there's no bbox to add GeomData = case Geom of - nil -> + <<>> -> []; _ -> - % XXX NOTE vmx 2012-11-28: Currently the first two dimensions are - % expected to be the bounding box of the geometry - % XXX vmx 2012-11-28: I'm not sure if a bounding box should be - % emitted at all. It's duplicated information you can get from - % the key yourself. - {[{W, E}, {S, N}], _} = lists:split(2, Mbb), - [ - {<<"bbox">>, [W, S, E, N]}, - {<<"geometry">>, - couch_spatial_updater:geocouch_to_geojsongeom(Geom)} - ] + {ok, JsonGeom} = wkb_reader:wkb_to_geojson(Geom), + [{<<"geometry">>, JsonGeom}] end, {[ {<<"id">>, DocId},