Skip to content

Instantly share code, notes, and snippets.

@nox
Created October 19, 2010 11:54
Show Gist options
  • Save nox/634075 to your computer and use it in GitHub Desktop.
Save nox/634075 to your computer and use it in GitHub Desktop.
read_geometry(Bytes = <<1, _Type, 0:24, _Rest/binary>>) ->
{Object, <<>>} = read_wkb(Bytes),
{geometry, {0, Object}};
read_geometry(<<SRID:32/little, Rest/binary>>) ->
{Object, <<>>} = read_wkb(Rest),
{geometry, {SRID, Object}}.
read_wkb(Bytes = <<1, 1, 0:24, _Rest/binary>>) ->
read_wkb_point(Bytes);
read_wkb(Bytes = <<1, 2, 0:24, _Rest/binary>>) ->
read_wkb_line_string(Bytes);
read_wkb(Bytes = <<1, 3, 0:24, _Rest/binary>>) ->
read_wkb_polygon(Bytes);
read_wkb(<<1, 4, 0:24, Rest/binary>>) ->
{MultiPoint, NewRest} = read_wkb_objects(Rest, fun read_wkb_point/1),
{{multi_point, MultiPoint}, NewRest};
read_wkb(<<1, 5, 0:24, Rest/binary>>) ->
{MultiLineString, NewRest} = read_wkb_objects(Rest, fun read_wkb_line_string/1),
{{multi_line_string, MultiLineString}, NewRest};
read_wkb(<<1, 6, 0:24, Rest/binary>>) ->
{MultiPolygon, NewRest} = read_wkb_objects(Rest, fun read_wkb_polygon/1),
{{multi_polygon, MultiPolygon}, NewRest};
read_wkb(<<1, 7, 0:24, Rest/binary>>) ->
{Collection, NewRest} = read_wkb_objects(Rest, fun read_wkb/1),
{{collection, Collection}, NewRest}.
read_wkb_point(<<1, 1, 0:24, Rest/binary>>) ->
read_point(Rest).
read_wkb_line_string(<<1, 2, 0:24, Rest/binary>>) ->
{LineString, NewRest} = read_points(Rest),
{{line_string, LineString}, NewRest}.
read_wkb_polygon(<<1, 3, 0:24, Rest/binary>>) ->
{Value, NewRest} = read_wkb_objects(Rest, fun read_linear_ring/1),
{{polygon, Value}, NewRest}.
read_point(<<X/little-float, Y/little-float, Rest/binary>>) ->
{{point, {X, Y}}, Rest}.
read_multiple(Bin, Count, ReadFun) ->
read_multiple(Bin, Count, ReadFun, []).
read_multiple(Rest, 0, _ReadFun, Values) ->
{lists:reverse(Values), Rest};
read_multiple(Bin, Count, ReadFun, Values) ->
{Value, Rest} = ReadFun(Bin),
read_multiple(Rest, Count - 1, ReadFun, [Value | Values]).
read_wkb_objects(<<Count:32/little, Rest/binary>>, ReadFun) ->
{Objects, NewRest} = read_multiple(Rest, Count, ReadFun),
{{Count, Objects}, NewRest}.
read_linear_ring(Bin) ->
{Value, Rest} = read_points(Bin),
{{linear_ring, Value}, Rest}.
read_points(Bin) ->
read_wkb_objects(Bin, fun read_point/1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment