1package Geo::JSON; 2 3our $VERSION = '0.007'; 4 5use strict; 6use warnings; 7use Carp; 8 9use JSON qw/ decode_json /; 10use List::Util qw/ first /; 11 12use constant GEOMETRY_OBJECTS => [ 13 qw/ Point MultiPoint LineString MultiLineString Polygon MultiPolygon GeometryCollection / 14]; 15use constant GEOJSON_OBJECTS => [ # 16 @{ +GEOMETRY_OBJECTS }, qw/ Feature FeatureCollection / 17]; 18 19our $json = JSON->new->utf8->convert_blessed(1); 20 21sub from_json { 22 my ( $class, $json ) = @_; 23 24 my $data = decode_json($json); 25 26 croak "from_json requires a JSON object (hashref)" 27 unless ref $data eq 'HASH'; 28 29 return $class->load($data); 30} 31 32sub load { 33 my ( $class, $data ) = @_; 34 35 my $type = delete $data->{type} 36 or croak "Invalid JSON data: no type specified"; 37 38 my $geo_json_class = 'Geo::JSON::' . $type; 39 40 croak "Invalid type '$type'" 41 unless first { $type eq $_ } @{ +GEOJSON_OBJECTS }; 42 43 eval "require $geo_json_class"; 44 45 return $geo_json_class->new($data); 46} 47 48sub codec { 49 my $class = shift; 50 51 my $orig = $json; 52 $json = shift if @_; 53 54 return $orig; 55} 56 571; 58 59__END__ 60 61=encoding utf-8 62 63=head1 NAME 64 65Geo::JSON - Perl OO interface for geojson 66 67=head1 SYNOPSIS 68 69 use Geo::JSON; 70 71 my $obj = Geo::JSON->from_json( $json ); 72 73 $obj->to_json(); 74 75=head1 DESCRIPTION 76 77Convert to and from geojson using Perl objects. GeoJSON objects represent 78various geographical positions - points, lines, polygons, etc. 79 80Currently supports 2 or 3 dimensions (longitude, latitude, altitude). Further 81dimensions in positions are ignored for calculations and comparisons, but will 82be read-from and written-to. 83 84=head1 GEOJSON SPECIFICATION 85 86See: L<http://www.geojson.org/geojson-spec.html> 87 88=head1 GEOJSON MEMBERS (ATTRIBUTES) 89 90See the specification for the full details, but the basics are as follows: 91 92=over 93 94=item * C<type> 95 96Determines the object the json will be turned into 97 98=item * C<position> 99 100Not explicitly named in the json, but an array of at least two numbers 101representing a location in x, y, z order (either Easting, Northing, Altitude 102or Longitude, Latitude, Altitude as appropriate). 103 104Additional numbers may be present but ignored by this package for 105calculations. 106 107=item * C<coordinates> 108 109Defined in geometry objects (Point, MultiPoint, LineString, MultiLineString, 110Polygon, MultiPolygon). Will consist of a single position (Point), an array 111of positions (MultiPoint, LineString), an array of arrays of positions 112(MultiLineString, Polygon) or an array of arrays of arrays of positions 113(MultiPolygon). The positions within a single object should all have the same 114number of axes and be in the same axis order. 115 116=item * C<bbox> 117 118Optional, defining a bounding box that the position(s) are contained by. 119 120The box is defined by a array of 2*n items, where n is the number of 121dimensions in a position. The items are the lowest value for an axis followed 122by the highest value for an axis, in the axis order used in the positions. 123 124The Co-ordinates Reference System for the bounding box is assumed to match 125that of the object. 126 127=item * C<crs> 128 129Optional, defining the Co-ordinates Reference System the object is using. See 130L<Geo::JSON::CRS> for more details. 131 132=back 133 134=head1 GEOMETRY OBJECTS 135 136=over 137 138=item * L<Geo::JSON::Point> 139 140A single position 141 142=item * L<Geo::JSON::MultiPoint> 143 144An array of positions, representing multiple points 145 146=item * L<Geo::JSON::LineString> 147 148An array of 2 or more positions, represening a connected line 149 150=item * L<Geo::JSON::MultiLineString> 151 152An array of lines 153 154=item * L<Geo::JSON::Polygon> 155 156An array of lines, defining a polygon. The first line represents the outside 157of the polygon, subsequent lines define any 'holes'. The lines must be 158'linear rings' - 4 or more points, with the first and last points being 159equivalent. 160 161=item * L<Geo::JSON::MultiPolygon> 162 163An array of polygons 164 165=item * L<Geo::JSON::GeometryCollection> 166 167An array of any of the above Geometry objects (as attribute C<geometries>) 168 169=back 170 171=head1 FEATURE OBJECTS 172 173=over 174 175=item * L<Geo::JSON::Feature> 176 177Any of the above objects (as attribute C<feature>), together with a data 178structure (as attruibute C<properties>) 179 180=back 181 182=head1 FEATURE COLLECTION OBJECTS 183 184=over 185 186=item * L<Geo::JSON::FeatureCollection> 187 188An array of Feature objects (as attribute C<features>) 189 190=back 191 192=head1 METHODS 193 194=head2 from_json 195 196 my $obj = Geo::JSON->from_json( $json ); 197 198Takes a geojson string, returns the object it represents. 199 200=head2 to_json 201 202 $obj->to_json(); 203 $obj->to_json( $codec ); 204 205Call on a Geo::JSON object. Returns the JSON that represents the object. 206 207Pass in an optional L<JSON> codec to modify the default behaviour of the JSON 208returned. 209 210=head2 load 211 212 my $obj = Geo::JSON->load( { type => 'Point', coordinates => ... } ); 213 214Creates a Geo::JSON object from a hashref. 215 216This is used for coercion of attributes during object creation, and probably 217should not be called directly otherwise. 218 219=head1 CLASS METHODS 220 221=head2 codec 222 223 Geo::JSON->codec->canonical(1)->pretty; 224 225 my $prev_codec = Geo::JSON->codec($new_codec); 226 227Set options on or replace L<JSON> codec. 228 229=head1 THANKS 230 231Tim Bunce - for codec suggestions and bug spotting. 232 233=head1 SEE ALSO 234 235=over 236 237=item * 238 239L<Geo::JSON::Simple> - simple interface to create Geo::JSON objects. 240 241=back 242 243=head1 SUPPORT 244 245=head2 Bugs / Feature Requests 246 247Please report any bugs or feature requests through the issue tracker 248at L<https://github.com/mjemmeson/Geo-JSON/issues>. 249You will be notified automatically of any progress on your issue. 250 251=head2 Source Code 252 253This is open source software. The code repository is available for 254public review and contribution under the terms of the license. 255 256L<https://github.com/mjemmeson/Geo-JSON> 257 258 git clone https://github.com/mjemmeson/Geo-JSON.git 259 260=head1 AUTHOR 261 262Michael Jemmeson <mjemmeson@cpan.org> 263 264=head1 COPYRIGHT AND LICENSE 265 266This software is copyright (c) 2015 by Michael Jemmeson <mjemmeson@cpan.org>. 267 268This is free software; you can redistribute it and/or modify it under 269the same terms as the Perl 5 programming language system itself. 270 271=cut 272 273