2015-07-10 11:05:48 +02:00
/*****************************************************************************
*
* This file is part of Mapnik ( c + + mapping toolkit )
*
* Copyright ( C ) 2015 Artem Pavlenko
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "catch.hpp"
2016-01-15 17:37:30 +01:00
# include "ds_test_util.hpp"
2015-07-10 11:05:48 +02:00
# include <mapnik/datasource.hpp>
# include <mapnik/datasource_cache.hpp>
# include <mapnik/geometry.hpp>
2015-10-19 13:23:43 +02:00
# include <mapnik/geometry_type.hpp>
2015-07-10 21:34:18 +02:00
# include <mapnik/util/fs.hpp>
2015-10-19 17:58:32 +02:00
# include <cstdlib>
2015-10-19 13:23:43 +02:00
2015-10-21 08:17:44 +02:00
# include <boost/optional/optional_io.hpp>
2015-10-21 07:56:03 +02:00
2015-10-29 16:01:36 +01:00
/*
Compile and run just this test :
clang + + - o test - geojson - g - I . / test / test / unit / run . cpp test / unit / datasource / geojson . cpp ` mapnik - config - - all - flags `
. / test - geojson - d yes
*/
2015-10-23 14:09:21 +02:00
namespace {
2015-10-19 13:23:43 +02:00
2015-10-21 08:17:44 +02:00
std : : pair < mapnik : : datasource_ptr , mapnik : : feature_ptr > fetch_first_feature ( std : : string const & filename , bool cache_features )
2015-10-19 13:23:43 +02:00
{
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
params [ " file " ] = filename ;
2015-10-22 16:53:23 +02:00
params [ " cache_features " ] = cache_features ;
2015-10-19 13:23:43 +02:00
auto ds = mapnik : : datasource_cache : : instance ( ) . create ( params ) ;
2015-10-21 18:15:07 +02:00
CHECK ( ds - > type ( ) = = mapnik : : datasource : : datasource_t : : Vector ) ;
2015-10-19 13:23:43 +02:00
auto fields = ds - > get_descriptor ( ) . get_descriptors ( ) ;
mapnik : : query query ( ds - > envelope ( ) ) ;
for ( auto const & field : fields )
{
query . add_property_name ( field . get_name ( ) ) ;
}
auto features = ds - > features ( query ) ;
auto feature = features - > next ( ) ;
2015-10-21 08:17:44 +02:00
return std : : make_pair ( ds , feature ) ;
2015-10-19 13:23:43 +02:00
}
}
2015-07-10 11:05:48 +02:00
TEST_CASE ( " geojson " ) {
2015-07-10 21:34:18 +02:00
std : : string geojson_plugin ( " ./plugins/input/geojson.input " ) ;
if ( mapnik : : util : : exists ( geojson_plugin ) )
2015-07-10 11:05:48 +02:00
{
2015-10-23 15:11:17 +02:00
SECTION ( " GeoJSON I/O errors " )
{
std : : string filename = " does_not_exist.geojson " ;
for ( auto create_index : { true , false } )
{
if ( create_index )
{
int ret = create_disk_index ( filename ) ;
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
// index wont be created
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
{
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
params [ " file " ] = filename ;
params [ " cache_features " ] = cache_features ;
REQUIRE_THROWS ( mapnik : : datasource_cache : : instance ( ) . create ( params ) ) ;
}
}
}
2015-10-23 15:17:41 +02:00
SECTION ( " GeoJSON invalid Point " )
{
for ( auto cache_features : { true , false } )
{
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
params [ " file " ] = " ./test/data/json/point-invalid.json " ;
params [ " cache_features " ] = cache_features ;
REQUIRE_THROWS ( mapnik : : datasource_cache : : instance ( ) . create ( params ) ) ;
}
}
2015-11-06 12:48:32 +01:00
SECTION ( " GeoJSON Point " )
2015-10-19 13:23:43 +02:00
{
2015-10-20 12:22:42 +02:00
for ( auto cache_features : { true , false } )
2015-10-19 13:23:43 +02:00
{
2015-10-23 14:09:21 +02:00
auto result = fetch_first_feature ( " ./test/data/json/point.json " , cache_features ) ;
2015-10-21 08:17:44 +02:00
auto feature = result . second ;
auto ds = result . first ;
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : Point ) ;
2015-10-19 13:23:43 +02:00
auto const & geometry = feature - > get_geometry ( ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( geometry ) = = mapnik : : geometry : : Point ) ;
auto const & pt = mapnik : : util : : get < mapnik : : geometry : : point < double > > ( geometry ) ;
REQUIRE ( pt . x = = 100 ) ;
REQUIRE ( pt . y = = 0 ) ;
}
}
SECTION ( " GeoJSON LineString " )
{
2015-10-20 12:22:42 +02:00
for ( auto cache_features : { true , false } )
2015-10-19 13:23:43 +02:00
{
2015-10-23 14:09:21 +02:00
auto result = fetch_first_feature ( " ./test/data/json/linestring.json " , cache_features ) ;
2015-10-21 08:17:44 +02:00
auto feature = result . second ;
auto ds = result . first ;
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : LineString ) ;
2015-10-19 13:23:43 +02:00
auto const & geometry = feature - > get_geometry ( ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( geometry ) = = mapnik : : geometry : : LineString ) ;
auto const & line = mapnik : : util : : get < mapnik : : geometry : : line_string < double > > ( geometry ) ;
REQUIRE ( line . size ( ) = = 2 ) ;
REQUIRE ( mapnik : : geometry : : envelope ( line ) = = mapnik : : box2d < double > ( 100 , 0 , 101 , 1 ) ) ;
}
}
SECTION ( " GeoJSON Polygon " )
{
2015-10-20 12:22:42 +02:00
for ( auto cache_features : { true , false } )
2015-10-19 13:23:43 +02:00
{
2015-10-23 14:09:21 +02:00
auto result = fetch_first_feature ( " ./test/data/json/polygon.json " , cache_features ) ;
2015-10-21 08:17:44 +02:00
auto feature = result . second ;
auto ds = result . first ;
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : Polygon ) ;
2015-10-19 13:23:43 +02:00
auto const & geometry = feature - > get_geometry ( ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( geometry ) = = mapnik : : geometry : : Polygon ) ;
auto const & poly = mapnik : : util : : get < mapnik : : geometry : : polygon < double > > ( geometry ) ;
REQUIRE ( poly . num_rings ( ) = = 2 ) ;
REQUIRE ( poly . exterior_ring . size ( ) = = 5 ) ;
REQUIRE ( poly . interior_rings . size ( ) = = 1 ) ;
REQUIRE ( poly . interior_rings [ 0 ] . size ( ) = = 5 ) ;
REQUIRE ( mapnik : : geometry : : envelope ( poly ) = = mapnik : : box2d < double > ( 100 , 0 , 101 , 1 ) ) ;
}
}
SECTION ( " GeoJSON MultiPoint " )
{
2015-10-20 12:22:42 +02:00
for ( auto cache_features : { true , false } )
2015-10-19 13:23:43 +02:00
{
2015-10-23 14:09:21 +02:00
auto result = fetch_first_feature ( " ./test/data/json/multipoint.json " , cache_features ) ;
2015-10-21 08:17:44 +02:00
auto feature = result . second ;
auto ds = result . first ;
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : Point ) ;
2015-10-19 13:23:43 +02:00
auto const & geometry = feature - > get_geometry ( ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( geometry ) = = mapnik : : geometry : : MultiPoint ) ;
auto const & multi_pt = mapnik : : util : : get < mapnik : : geometry : : multi_point < double > > ( geometry ) ;
REQUIRE ( multi_pt . size ( ) = = 2 ) ;
REQUIRE ( mapnik : : geometry : : envelope ( multi_pt ) = = mapnik : : box2d < double > ( 100 , 0 , 101 , 1 ) ) ;
}
}
SECTION ( " GeoJSON MultiLineString " )
{
2015-10-20 12:22:42 +02:00
for ( auto cache_features : { true , false } )
2015-10-19 13:23:43 +02:00
{
2015-10-23 14:09:21 +02:00
auto result = fetch_first_feature ( " ./test/data/json/multilinestring.json " , cache_features ) ;
2015-10-21 08:17:44 +02:00
auto feature = result . second ;
auto ds = result . first ;
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : LineString ) ;
2015-10-19 13:23:43 +02:00
auto const & geometry = feature - > get_geometry ( ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( geometry ) = = mapnik : : geometry : : MultiLineString ) ;
auto const & multi_line = mapnik : : util : : get < mapnik : : geometry : : multi_line_string < double > > ( geometry ) ;
REQUIRE ( multi_line . size ( ) = = 2 ) ;
REQUIRE ( multi_line [ 0 ] . size ( ) = = 2 ) ;
REQUIRE ( multi_line [ 1 ] . size ( ) = = 2 ) ;
REQUIRE ( mapnik : : geometry : : envelope ( multi_line ) = = mapnik : : box2d < double > ( 100 , 0 , 103 , 3 ) ) ;
}
}
SECTION ( " GeoJSON MultiPolygon " )
{
2015-10-20 12:22:42 +02:00
for ( auto cache_features : { true , false } )
2015-10-19 13:23:43 +02:00
{
2015-10-23 14:09:21 +02:00
auto result = fetch_first_feature ( " ./test/data/json/multipolygon.json " , cache_features ) ;
2015-10-21 08:17:44 +02:00
auto feature = result . second ;
auto ds = result . first ;
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : Polygon ) ;
2015-10-19 13:23:43 +02:00
// test
auto const & geometry = feature - > get_geometry ( ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( geometry ) = = mapnik : : geometry : : MultiPolygon ) ;
auto const & multi_poly = mapnik : : util : : get < mapnik : : geometry : : multi_polygon < double > > ( geometry ) ;
REQUIRE ( multi_poly . size ( ) = = 2 ) ;
REQUIRE ( multi_poly [ 0 ] . num_rings ( ) = = 1 ) ;
REQUIRE ( multi_poly [ 1 ] . num_rings ( ) = = 2 ) ;
REQUIRE ( mapnik : : geometry : : envelope ( multi_poly ) = = mapnik : : box2d < double > ( 100 , 0 , 103 , 3 ) ) ;
}
}
SECTION ( " GeoJSON GeometryCollection " )
{
2015-10-21 07:56:03 +02:00
std : : string filename ( " ./test/data/json/geometrycollection.json " ) ;
for ( auto create_index : { true , false } )
2015-10-19 13:23:43 +02:00
{
2015-10-21 07:56:03 +02:00
if ( create_index )
{
2015-10-23 14:09:21 +02:00
int ret = create_disk_index ( filename ) ;
2015-10-21 07:56:03 +02:00
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
// index will not exist because this is not a featurecollection
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
{
2015-10-23 14:09:21 +02:00
auto result = fetch_first_feature ( filename , cache_features ) ;
2015-10-21 08:17:44 +02:00
auto feature = result . second ;
auto ds = result . first ;
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : Collection ) ;
2015-10-21 07:56:03 +02:00
// test
auto const & geometry = feature - > get_geometry ( ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( geometry ) = = mapnik : : geometry : : GeometryCollection ) ;
auto const & collection = mapnik : : util : : get < mapnik : : geometry : : geometry_collection < double > > ( geometry ) ;
REQUIRE ( collection . size ( ) = = 2 ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( collection [ 0 ] ) = = mapnik : : geometry : : Point ) ;
REQUIRE ( mapnik : : geometry : : geometry_type ( collection [ 1 ] ) = = mapnik : : geometry : : LineString ) ;
REQUIRE ( mapnik : : geometry : : envelope ( collection ) = = mapnik : : box2d < double > ( 100 , 0 , 102 , 1 ) ) ;
}
2015-10-19 13:23:43 +02:00
}
}
2015-10-20 13:04:32 +02:00
SECTION ( " GeoJSON Feature " )
{
// Create datasource
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
2015-10-22 17:45:34 +02:00
std : : string base ( " ./test/data/json/ " ) ;
std : : string file ( " feature.json " ) ;
params [ " base " ] = base ;
params [ " file " ] = file ;
std : : string filename = base + file ;
2015-10-21 07:56:03 +02:00
for ( auto create_index : { true , false } )
2015-10-20 13:04:32 +02:00
{
2015-10-21 07:56:03 +02:00
if ( create_index )
{
2015-10-23 14:09:21 +02:00
int ret = create_disk_index ( filename ) ;
2015-10-21 07:56:03 +02:00
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
// index will not exist because this is not a featurecollection
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
2015-10-20 13:04:32 +02:00
{
2015-10-22 17:13:08 +02:00
params [ " cache_features " ] = cache_features ;
2015-10-21 07:56:03 +02:00
auto ds = mapnik : : datasource_cache : : instance ( ) . create ( params ) ;
REQUIRE ( bool ( ds ) ) ;
2015-10-21 18:15:07 +02:00
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : Point ) ;
2015-10-21 07:56:03 +02:00
auto fields = ds - > get_descriptor ( ) . get_descriptors ( ) ;
mapnik : : query query ( ds - > envelope ( ) ) ;
for ( auto const & field : fields )
{
query . add_property_name ( field . get_name ( ) ) ;
}
auto features = ds - > features ( query ) ;
2015-10-21 21:37:30 +02:00
auto features2 = ds - > features_at_point ( ds - > envelope ( ) . center ( ) , 0 ) ;
2015-10-21 07:56:03 +02:00
REQUIRE ( features ! = nullptr ) ;
2015-10-21 21:37:30 +02:00
REQUIRE ( features2 ! = nullptr ) ;
2015-10-21 07:56:03 +02:00
auto feature = features - > next ( ) ;
2015-10-21 21:37:30 +02:00
auto feature2 = features2 - > next ( ) ;
2015-10-21 07:56:03 +02:00
REQUIRE ( feature ! = nullptr ) ;
2015-10-21 21:37:30 +02:00
REQUIRE ( feature2 ! = nullptr ) ;
CHECK ( feature - > id ( ) = = 1 ) ;
CHECK ( feature2 - > id ( ) = = 1 ) ;
mapnik : : value val = feature - > get ( " name " ) ;
CHECK ( val . to_string ( ) = = " Dinagat Islands " ) ;
mapnik : : value val2 = feature2 - > get ( " name " ) ;
CHECK ( val2 . to_string ( ) = = " Dinagat Islands " ) ;
REQUIRE ( features - > next ( ) = = nullptr ) ;
REQUIRE ( features2 - > next ( ) = = nullptr ) ;
2015-10-20 13:04:32 +02:00
}
}
}
2015-10-20 12:46:39 +02:00
SECTION ( " GeoJSON FeatureCollection " )
2015-10-19 17:58:32 +02:00
{
std : : string filename ( " ./test/data/json/featurecollection.json " ) ;
2015-10-20 12:46:39 +02:00
2015-10-21 07:56:03 +02:00
// cleanup in the case of a failed previous run
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
2015-10-23 19:39:55 +02:00
mapnik : : util : : remove ( filename + " .index " ) ;
2015-10-21 07:56:03 +02:00
}
2015-10-20 12:46:39 +02:00
for ( auto create_index : { true , false } )
2015-10-19 17:58:32 +02:00
{
2015-10-20 12:46:39 +02:00
if ( create_index )
{
2015-10-23 14:09:21 +02:00
int ret = create_disk_index ( filename ) ;
2015-10-21 00:18:12 +02:00
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
2015-10-20 21:23:05 +02:00
INFO ( ret ) ;
2015-10-21 00:18:12 +02:00
INFO ( ret_posix ) ;
2015-10-20 21:19:06 +02:00
CHECK ( mapnik : : util : : exists ( filename + " .index " ) ) ;
2015-10-20 12:46:39 +02:00
}
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
params [ " file " ] = filename ;
for ( auto cache_features : { true , false } )
2015-10-19 17:58:32 +02:00
{
2015-10-20 12:46:39 +02:00
params [ " cache_features " ] = cache_features ;
2015-10-19 17:58:32 +02:00
auto ds = mapnik : : datasource_cache : : instance ( ) . create ( params ) ;
2015-10-21 18:15:07 +02:00
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : Collection ) ;
2015-10-19 17:58:32 +02:00
auto fields = ds - > get_descriptor ( ) . get_descriptors ( ) ;
mapnik : : query query ( ds - > envelope ( ) ) ;
for ( auto const & field : fields )
{
query . add_property_name ( field . get_name ( ) ) ;
}
auto features = ds - > features ( query ) ;
2015-10-21 21:37:30 +02:00
auto features2 = ds - > features_at_point ( ds - > envelope ( ) . center ( ) , 10 ) ;
2015-10-19 17:58:32 +02:00
auto bounding_box = ds - > envelope ( ) ;
mapnik : : box2d < double > bbox ;
2015-10-20 12:46:39 +02:00
mapnik : : value_integer count = 0 ;
2015-10-19 17:58:32 +02:00
while ( true )
{
auto feature = features - > next ( ) ;
2015-10-21 21:37:30 +02:00
auto feature2 = features2 - > next ( ) ;
if ( ! feature | | ! feature2 ) break ;
2015-10-19 17:58:32 +02:00
if ( ! bbox . valid ( ) ) bbox = feature - > envelope ( ) ;
else bbox . expand_to_include ( feature - > envelope ( ) ) ;
+ + count ;
2015-10-20 12:46:39 +02:00
REQUIRE ( feature - > id ( ) = = count ) ;
2015-10-21 21:37:30 +02:00
REQUIRE ( feature2 - > id ( ) = = count ) ;
2015-10-19 17:58:32 +02:00
}
REQUIRE ( count = = 3 ) ;
REQUIRE ( bounding_box = = bbox ) ;
2015-10-20 12:46:39 +02:00
}
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
2015-10-19 17:58:32 +02:00
CHECK ( mapnik : : util : : remove ( filename + " .index " ) ) ;
}
}
}
2015-10-20 13:04:32 +02:00
SECTION ( " GeoJSON extra properties " )
2015-07-17 17:43:04 +02:00
{
// Create datasource
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
2015-10-21 07:56:03 +02:00
std : : string filename ( " ./test/data/json/feature_collection_extra_properties.json " ) ;
params [ " file " ] = filename ;
// cleanup in the case of a failed previous run
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
2015-10-23 19:39:55 +02:00
mapnik : : util : : remove ( filename + " .index " ) ;
2015-10-21 07:56:03 +02:00
}
for ( auto create_index : { true , false } )
2015-07-17 17:43:04 +02:00
{
2015-10-21 07:56:03 +02:00
if ( create_index )
{
2015-10-23 14:09:21 +02:00
int ret = create_disk_index ( filename ) ;
2015-10-21 07:56:03 +02:00
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
CHECK ( mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
{
2015-10-22 17:13:08 +02:00
params [ " cache_features " ] = cache_features ;
2015-10-21 07:56:03 +02:00
auto ds = mapnik : : datasource_cache : : instance ( ) . create ( params ) ;
2015-10-21 18:15:07 +02:00
CHECK ( ds - > get_geometry_type ( ) = = mapnik : : datasource_geometry_t : : Point ) ;
2015-10-21 07:56:03 +02:00
REQUIRE ( bool ( ds ) ) ;
auto fields = ds - > get_descriptor ( ) . get_descriptors ( ) ;
mapnik : : query query ( ds - > envelope ( ) ) ;
for ( auto const & field : fields )
{
query . add_property_name ( field . get_name ( ) ) ;
}
auto features = ds - > features ( query ) ;
REQUIRE ( features ! = nullptr ) ;
auto feature = features - > next ( ) ;
REQUIRE ( feature ! = nullptr ) ;
REQUIRE ( feature - > envelope ( ) = = mapnik : : box2d < double > ( 123 , 456 , 123 , 456 ) ) ;
}
// cleanup
if ( create_index & & mapnik : : util : : exists ( filename + " .index " ) )
2015-10-20 13:04:32 +02:00
{
2015-10-23 19:39:55 +02:00
mapnik : : util : : remove ( filename + " .index " ) ;
2015-10-20 13:04:32 +02:00
}
2015-10-21 07:56:03 +02:00
2015-07-17 17:43:04 +02:00
}
}
2015-11-06 12:48:32 +01:00
SECTION ( " GeoJSON ensure mapnik::datasource_cache::instance().create() throws on malformed input " )
{
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
for ( auto const & c_str : { " ./test/data/json/feature-malformed-1.geojson " ,
" ./test/data/json/feature-malformed-2.geojson " ,
" ./test/data/json/feature-malformed-3.geojson " } )
{
std : : string filename ( c_str ) ;
2015-11-10 12:37:48 +01:00
params [ " file " ] = filename ;
2015-11-06 12:48:32 +01:00
// cleanup in the case of a failed previous run
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
for ( auto create_index : { true , false } )
{
if ( create_index )
{
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
int ret = create_disk_index ( filename ) ;
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
{
2015-11-10 12:37:48 +01:00
params [ " cache_features " ] = cache_features ;
2015-11-06 12:48:32 +01:00
CHECK_THROWS ( mapnik : : datasource_cache : : instance ( ) . create ( params ) ) ;
}
// cleanup
if ( create_index & & mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
}
}
}
2015-11-10 12:37:48 +01:00
SECTION ( " GeoJSON ensure mapnik::featureset::next() throws on malformed input " )
{
std : : string filename { " ./test/data/json/featurecollection-malformed.json " } ;
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
params [ " file " ] = filename ;
// cleanup in the case of a failed previous run
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
int ret = create_disk_index ( filename ) ;
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
CHECK ( mapnik : : util : : exists ( filename + " .index " ) ) ;
for ( auto cache_features : { true , false } )
{
2015-11-25 13:46:21 +01:00
params [ " cache_features " ] = cache_features ;
2015-11-10 12:37:48 +01:00
auto ds = mapnik : : datasource_cache : : instance ( ) . create ( params ) ;
auto fields = ds - > get_descriptor ( ) . get_descriptors ( ) ;
mapnik : : query query ( ds - > envelope ( ) ) ;
auto features = ds - > features ( query ) ;
REQUIRE_THROWS (
auto feature = features - > next ( ) ;
while ( feature ! = nullptr )
{
feature = features - > next ( ) ;
} ) ;
}
// cleanup
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
}
2015-10-20 13:04:32 +02:00
SECTION ( " GeoJSON ensure input fully consumed and throw exception otherwise " )
2015-07-17 17:43:04 +02:00
{
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
2015-11-06 12:48:32 +01:00
2015-10-21 07:56:03 +02:00
std : : string filename ( " ./test/data/json/points-malformed.geojson " ) ;
params [ " file " ] = filename ; // mismatched parentheses
// cleanup in the case of a failed previous run
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
2015-10-23 19:39:55 +02:00
mapnik : : util : : remove ( filename + " .index " ) ;
2015-10-21 07:56:03 +02:00
}
for ( auto create_index : { true , false } )
2015-07-17 17:43:04 +02:00
{
2015-10-21 07:56:03 +02:00
if ( create_index )
{
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
2015-10-23 14:09:21 +02:00
int ret = create_disk_index ( filename ) ;
2015-10-21 07:56:03 +02:00
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
CHECK ( mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
{
2015-10-22 19:28:31 +02:00
// unfortunately when using an index or not
// caching features we use the bbox grammar
// which is not strict (and would be a perf hit if it were strict).
// So this is one known hole where invalid data may silently parse okay
// refs https://github.com/mapnik/mapnik/issues/3125
if ( ! create_index & & cache_features = = true )
2015-10-22 17:19:39 +02:00
{
std : : stringstream msg ;
msg < < " testcase: create index " < < create_index < < " cache_features " < < cache_features ;
params [ " cache_features " ] = cache_features ;
INFO ( msg . str ( ) ) ;
CHECK_THROWS ( mapnik : : datasource_cache : : instance ( ) . create ( params ) ) ;
}
2015-10-21 07:56:03 +02:00
}
// cleanup
if ( create_index & & mapnik : : util : : exists ( filename + " .index " ) )
{
2015-10-23 19:39:55 +02:00
mapnik : : util : : remove ( filename + " .index " ) ;
2015-10-21 07:56:03 +02:00
}
2015-07-17 17:43:04 +02:00
}
2015-10-14 12:41:14 +02:00
}
2015-11-25 13:46:21 +01:00
SECTION ( " GeoJSON ensure original feature ordering is preserved " )
{
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
std : : string filename ( " ./test/data/json/ordered.json " ) ;
params [ " file " ] = filename ;
// cleanup in the case of a failed previous run
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
for ( auto create_index : { true , false } )
{
if ( create_index )
{
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
int ret = create_disk_index ( filename ) ;
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
CHECK ( mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
{
params [ " cache_features " ] = cache_features ;
auto ds = mapnik : : datasource_cache : : instance ( ) . create ( params ) ;
REQUIRE ( bool ( ds ) ) ;
auto fields = ds - > get_descriptor ( ) . get_descriptors ( ) ;
mapnik : : query query ( ds - > envelope ( ) ) ;
for ( auto const & field : fields )
{
query . add_property_name ( field . get_name ( ) ) ;
}
auto features = ds - > features ( query ) ;
auto feature = features - > next ( ) ;
mapnik : : value_integer count = 0 ;
while ( feature ! = nullptr )
{
// ids are in ascending order, starting from 1
mapnik : : value val = feature - > get ( " id " ) ;
REQUIRE ( val . get < mapnik : : value_integer > ( ) = = + + count ) ;
feature = features - > next ( ) ;
}
}
// cleanup
if ( create_index & & mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
}
}
2016-01-15 17:37:30 +01:00
SECTION ( " GeoJSON descriptor returns all field names " )
{
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
std : : string filename ( " ./test/data/json/featurecollection-multipleprops.geojson " ) ;
params [ " file " ] = filename ;
// cleanup in the case of a failed previous run
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
for ( auto create_index : { true , false } )
{
if ( create_index )
{
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
int ret = create_disk_index ( filename ) ;
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
CHECK ( mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
{
params [ " cache_features " ] = cache_features ;
auto ds = mapnik : : datasource_cache : : instance ( ) . create ( params ) ;
REQUIRE ( bool ( ds ) ) ;
auto fields = ds - > get_descriptor ( ) . get_descriptors ( ) ;
2016-02-25 15:30:36 +01:00
std : : initializer_list < std : : string > names = { " one " , " two " } ;
REQUIRE_FIELD_NAMES ( fields , names ) ;
2016-01-15 17:37:30 +01:00
}
// cleanup
if ( create_index & & mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
}
}
2016-05-05 18:17:08 +02:00
SECTION ( " GeoJSON properties are properly expressed " )
{
mapnik : : parameters params ;
params [ " type " ] = " geojson " ;
std : : string filename ( " ./test/data/json/escaped.geojson " ) ;
params [ " file " ] = filename ;
// cleanup in the case of a failed previous run
if ( mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
for ( auto create_index : { true , false } )
{
if ( create_index )
{
CHECK ( ! mapnik : : util : : exists ( filename + " .index " ) ) ;
int ret = create_disk_index ( filename ) ;
int ret_posix = ( ret > > 8 ) & 0x000000ff ;
INFO ( ret ) ;
INFO ( ret_posix ) ;
CHECK ( mapnik : : util : : exists ( filename + " .index " ) ) ;
}
for ( auto cache_features : { true , false } )
{
params [ " cache_features " ] = cache_features ;
auto ds = mapnik : : datasource_cache : : instance ( ) . create ( params ) ;
REQUIRE ( bool ( ds ) ) ;
auto fields = ds - > get_descriptor ( ) . get_descriptors ( ) ;
std : : initializer_list < std : : string > names = { " NOM_FR " , " array " , " boolean " , " description " , " double " , " int " , " name " , " object " , " spaces " } ;
REQUIRE_FIELD_NAMES ( fields , names ) ;
auto fs = all_features ( ds ) ;
REQUIRE ( bool ( fs ) ) ;
std : : initializer_list < attr > attrs = {
attr { " name " , mapnik : : value_unicode_string ( " Test " ) } ,
attr { " NOM_FR " , mapnik : : value_unicode_string ( " Québec " ) } ,
attr { " bool " , mapnik : : value_bool ( " true " ) } ,
attr { " description " , mapnik : : value_unicode_string ( " Test: \u005C " ) } ,
attr { " double " , mapnik : : value_double ( 1.1 ) } ,
attr { " int " , mapnik : : value_integer ( 1 ) } ,
attr { " object " , mapnik : : value_unicode_string ( " { \" name \" : \" waka \" , \" spaces \" : \" value with spaces \" , \" int \" : 1, \" double \" :1.1, \" boolean \" :false, \" NOM_FR \" : \" Québec \" } " ) } ,
attr { " spaces " , mapnik : : value_unicode_string ( " this has spaces " ) } ,
attr { " array " , mapnik : : value_unicode_string ( " [ \" string \" , \" value with spaces \" ,3,1.1,null,true, \" Québec \" ] " ) }
} ;
auto feature = fs - > next ( ) ;
REQUIRE ( bool ( feature ) ) ;
REQUIRE_ATTRIBUTES ( feature , attrs ) ;
}
// cleanup
if ( create_index & & mapnik : : util : : exists ( filename + " .index " ) )
{
mapnik : : util : : remove ( filename + " .index " ) ;
}
}
}
2015-07-10 21:34:18 +02:00
}
2015-07-10 11:05:48 +02:00
}