[magics] 01/01: New upstream 2.34.1
Alastair McKinstry
mckinstry at moszumanska.debian.org
Mon Jul 17 14:21:28 UTC 2017
This is an automated email from the git hooks/post-receive script.
mckinstry pushed a commit to tag upstream/2.34.1
in repository magics.
commit c74b73c91f54cedd8ff4378328c3f30ae71421a0
Author: Alastair McKinstry <mckinstry at debian.org>
Date: Mon Jul 17 15:20:46 2017 +0100
New upstream 2.34.1
---
CMakeLists.txt | 6 +-
VERSION.cmake | 3 +-
magics.sublime-project | 2 +-
notebook/2t.json | 446 --
notebook/Cross-section.ipynb | 63 -
notebook/Untitled.ipynb | 59 -
notebook/Untitled1.ipynb | 47 -
notebook/WCS.ipynb | 16 +-
notebook/WMS.ipynb | 136 -
notebook/array-mars.ipynb | 345 --
notebook/boxplot.ipynb | 224 -
notebook/cartesian_projection.ipynb | 354 --
notebook/curve-python3.ipynb | 163 -
notebook/epsgrams.ipynb | 62 +-
notebook/grib-mars.ipynb | 218 -
notebook/hcc.json | 446 --
notebook/lcc.json | 446 --
notebook/magics-netcdf.ipynb | 520 --
notebook/magics1.ipynb | 226 -
notebook/mcc.json | 446 --
notebook/mongo.ipynb | 217 -
notebook/read.py | 27 -
notebook/sf.json | 446 --
notebook/tcc.json | 446 --
notebook/tp.json | 446 --
python/CMakeLists.txt | 22 +-
python/Magics.i.in | 69 +
python/Magics.py.in | 499 --
python/Magics/macro.py | 186 +-
python/Magics/metgram.py | 47 +-
python/Magics/toolbox.py | 93 +-
python/Magics_interface.cc | 255 +
python/numpy.i | 1634 ++++++
python/setup.py.in | 18 +
python/test_for_ctypes/array.py | 57 -
python/test_for_ctypes/test_ctypes.py | 28 -
python/test_for_ctypes/test_ctypes_graph.py | 58 -
src/basic/Layer.cc | 95 +-
src/basic/Layer.h | 30 +-
src/basic/MagicsEvent.h | 37 +-
src/basic/ViewNode.cc | 55 +-
src/basic/ViewNode.h | 5 +-
src/basic/VisualAction.cc | 7 +-
src/boost/README.update_boost | 23 +
src/boost/geometry/algorithms/append.hpp | 233 +
src/boost/geometry/algorithms/area.hpp | 295 +
src/boost/geometry/algorithms/assign.hpp | 171 +
src/boost/geometry/algorithms/buffer.hpp | 167 +
src/boost/geometry/algorithms/centroid.hpp | 470 ++
src/boost/geometry/algorithms/clear.hpp | 159 +
.../geometry/algorithms/comparable_distance.hpp | 74 +
src/boost/geometry/algorithms/convert.hpp | 411 ++
src/boost/geometry/algorithms/convex_hull.hpp | 275 +
src/boost/geometry/algorithms/correct.hpp | 265 +
src/boost/geometry/algorithms/covered_by.hpp | 195 +
src/boost/geometry/algorithms/detail/as_range.hpp | 107 +
.../algorithms/detail/assign_box_corners.hpp | 93 +
.../algorithms/detail/assign_indexed_point.hpp | 94 +
.../geometry/algorithms/detail/assign_values.hpp | 443 ++
.../geometry/algorithms/detail/calculate_null.hpp | 38 +
.../geometry/algorithms/detail/calculate_sum.hpp | 64 +
.../detail/convert_indexed_to_indexed.hpp | 80 +
.../algorithms/detail/convert_point_to_point.hpp | 68 +
src/boost/geometry/algorithms/detail/disjoint.hpp | 225 +
.../algorithms/detail/equals/collect_vectors.hpp | 315 +
.../geometry/algorithms/detail/for_each_range.hpp | 149 +
.../geometry/algorithms/detail/get_left_turns.hpp | 367 ++
.../algorithms/detail/has_self_intersections.hpp | 120 +
src/boost/geometry/algorithms/detail/not.hpp | 50 +
.../geometry/algorithms/detail/occupation_info.hpp | 329 ++
.../algorithms/detail/overlay/add_rings.hpp | 160 +
.../detail/overlay/append_no_duplicates.hpp | 53 +
.../algorithms/detail/overlay/assign_parents.hpp | 338 ++
.../detail/overlay/backtrack_check_si.hpp | 170 +
.../detail/overlay/calculate_distance_policy.hpp | 64 +
.../algorithms/detail/overlay/check_enrich.hpp | 172 +
.../algorithms/detail/overlay/clip_linestring.hpp | 242 +
.../algorithms/detail/overlay/convert_ring.hpp | 99 +
.../detail/overlay/copy_segment_point.hpp | 295 +
.../algorithms/detail/overlay/copy_segments.hpp | 328 ++
.../algorithms/detail/overlay/debug_turn_info.hpp | 66 +
.../detail/overlay/enrich_intersection_points.hpp | 523 ++
.../algorithms/detail/overlay/enrichment_info.hpp | 76 +
.../geometry/algorithms/detail/overlay/follow.hpp | 416 ++
.../detail/overlay/get_intersection_points.hpp | 146 +
.../detail/overlay/get_relative_order.hpp | 108 +
.../algorithms/detail/overlay/get_ring.hpp | 102 +
.../algorithms/detail/overlay/get_turn_info.hpp | 1094 ++++
.../algorithms/detail/overlay/get_turns.hpp | 873 +++
.../detail/overlay/handle_tangencies.hpp | 672 +++
.../detail/overlay/intersection_insert.hpp | 690 +++
.../geometry/algorithms/detail/overlay/overlay.hpp | 301 +
.../algorithms/detail/overlay/overlay_type.hpp | 29 +
.../algorithms/detail/overlay/ring_properties.hpp | 78 +
.../detail/overlay/segment_identifier.hpp | 91 +
.../algorithms/detail/overlay/select_rings.hpp | 295 +
.../algorithms/detail/overlay/self_turn_points.hpp | 308 +
.../algorithms/detail/overlay/stream_info.hpp | 75 +
.../algorithms/detail/overlay/traversal_info.hpp | 47 +
.../algorithms/detail/overlay/traverse.hpp | 395 ++
.../algorithms/detail/overlay/turn_info.hpp | 152 +
.../algorithms/detail/overlay/visit_info.hpp | 136 +
.../algorithms/detail/overlay/within_util.hpp | 98 +
src/boost/geometry/algorithms/detail/partition.hpp | 425 ++
.../geometry/algorithms/detail/point_on_border.hpp | 246 +
.../geometry/algorithms/detail/ring_identifier.hpp | 70 +
.../detail/sections/range_by_section.hpp | 131 +
.../algorithms/detail/sections/sectionalize.hpp | 648 +++
.../algorithms/detail/throw_on_empty_input.hpp | 53 +
src/boost/geometry/algorithms/difference.hpp | 160 +
src/boost/geometry/algorithms/disjoint.hpp | 301 +
src/boost/geometry/algorithms/distance.hpp | 591 ++
src/boost/geometry/algorithms/envelope.hpp | 273 +
src/boost/geometry/algorithms/equals.hpp | 319 +
src/boost/geometry/algorithms/expand.hpp | 319 +
src/boost/geometry/algorithms/for_each.hpp | 358 ++
src/boost/geometry/algorithms/intersection.hpp | 237 +
src/boost/geometry/algorithms/intersects.hpp | 106 +
src/boost/geometry/algorithms/length.hpp | 204 +
src/boost/geometry/algorithms/make.hpp | 200 +
src/boost/geometry/algorithms/not_implemented.hpp | 117 +
src/boost/geometry/algorithms/num_geometries.hpp | 95 +
.../geometry/algorithms/num_interior_rings.hpp | 88 +
src/boost/geometry/algorithms/num_points.hpp | 171 +
src/boost/geometry/algorithms/overlaps.hpp | 202 +
src/boost/geometry/algorithms/perimeter.hpp | 144 +
src/boost/geometry/algorithms/reverse.hpp | 134 +
src/boost/geometry/algorithms/simplify.hpp | 405 ++
src/boost/geometry/algorithms/sym_difference.hpp | 177 +
src/boost/geometry/algorithms/touches.hpp | 181 +
src/boost/geometry/algorithms/transform.hpp | 351 ++
src/boost/geometry/algorithms/union.hpp | 284 +
src/boost/geometry/algorithms/unique.hpp | 153 +
src/boost/geometry/algorithms/within.hpp | 344 ++
src/boost/geometry/arithmetic/arithmetic.hpp | 281 +
src/boost/geometry/arithmetic/determinant.hpp | 76 +
src/boost/geometry/arithmetic/dot_product.hpp | 82 +
src/boost/geometry/core/access.hpp | 324 ++
src/boost/geometry/core/closure.hpp | 180 +
src/boost/geometry/core/coordinate_dimension.hpp | 126 +
src/boost/geometry/core/coordinate_system.hpp | 97 +
src/boost/geometry/core/coordinate_type.hpp | 102 +
src/boost/geometry/core/cs.hpp | 220 +
src/boost/geometry/core/exception.hpp | 60 +
src/boost/geometry/core/exterior_ring.hpp | 144 +
src/boost/geometry/core/geometry_id.hpp | 94 +
src/boost/geometry/core/interior_rings.hpp | 139 +
src/boost/geometry/core/interior_type.hpp | 161 +
src/boost/geometry/core/is_areal.hpp | 60 +
src/boost/geometry/core/mutable_range.hpp | 98 +
src/boost/geometry/core/point_order.hpp | 162 +
src/boost/geometry/core/point_type.hpp | 130 +
src/boost/geometry/core/radian_access.hpp | 152 +
src/boost/geometry/core/reverse_dispatch.hpp | 67 +
src/boost/geometry/core/ring_type.hpp | 170 +
src/boost/geometry/core/tag.hpp | 70 +
src/boost/geometry/core/tag_cast.hpp | 84 +
src/boost/geometry/core/tags.hpp | 94 +
src/boost/geometry/core/topological_dimension.hpp | 88 +
src/boost/geometry/domains/gis/io/io.hpp | 65 +
.../geometry/domains/gis/io/wkt/detail/wkt.hpp | 49 +
.../domains/gis/io/wkt/detail/wkt_multi.hpp | 56 +
src/boost/geometry/domains/gis/io/wkt/read_wkt.hpp | 692 +++
.../geometry/domains/gis/io/wkt/read_wkt_multi.hpp | 112 +
src/boost/geometry/domains/gis/io/wkt/wkt.hpp | 25 +
.../geometry/domains/gis/io/wkt/write_wkt.hpp | 394 ++
.../domains/gis/io/wkt/write_wkt_multi.hpp | 117 +
.../algorithms/buffer/intersecting_inserter.hpp | 93 +
.../algorithms/buffer/line_line_intersection.hpp | 84 +
.../algorithms/buffer/linestring_buffer.hpp | 223 +
.../algorithms/buffer/polygon_buffer.hpp | 231 +
.../algorithms/buffer/remove_within_distance.hpp | 151 +
.../algorithms/buffer/sectionalizing_buffer.hpp | 167 +
.../algorithms/buffer/segmenting_buffer.hpp | 350 ++
.../algorithms/buffer/splitting_buffer.hpp | 116 +
.../algorithms/buffer/traversing_buffer.hpp | 89 +
.../geometry/extensions/algorithms/connect.hpp | 581 ++
.../algorithms/detail/overlay/dissolver.hpp | 640 +++
.../algorithms/detail/overlay/msm_state.hpp | 187 +
.../algorithms/detail/overlay/split_rings.hpp | 547 ++
.../geometry/extensions/algorithms/dissolve.hpp | 293 +
.../geometry/extensions/algorithms/mark_spikes.hpp | 516 ++
.../geometry/extensions/algorithms/midpoints.hpp | 131 +
.../geometry/extensions/algorithms/offset.hpp | 204 +
src/boost/geometry/extensions/algorithms/parse.hpp | 123 +
.../extensions/algorithms/point_on_line.hpp | 75 +
.../extensions/algorithms/remove_holes_if.hpp | 166 +
.../extensions/algorithms/remove_marked.hpp | 224 +
.../extensions/algorithms/remove_spikes.hpp | 378 ++
.../geometry/extensions/algorithms/selected.hpp | 278 +
.../extensions/arithmetic/cross_product.hpp | 109 +
.../geometry/extensions/astronomy/core/cs.hpp | 53 +
.../geometry/extensions/contrib/ttmath/ttmath.h | 2849 +++++++++
.../geometry/extensions/contrib/ttmath/ttmathbig.h | 6064 ++++++++++++++++++++
.../geometry/extensions/contrib/ttmath/ttmathint.h | 1922 +++++++
.../extensions/contrib/ttmath/ttmathmisc.h | 250 +
.../extensions/contrib/ttmath/ttmathobjects.h | 809 +++
.../extensions/contrib/ttmath/ttmathparser.h | 2777 +++++++++
.../extensions/contrib/ttmath/ttmaththreads.h | 250 +
.../extensions/contrib/ttmath/ttmathtypes.h | 675 +++
.../extensions/contrib/ttmath/ttmathuint.h | 4121 +++++++++++++
.../extensions/contrib/ttmath/ttmathuint_noasm.h | 1017 ++++
.../extensions/contrib/ttmath/ttmathuint_x86.h | 1602 ++++++
.../extensions/contrib/ttmath/ttmathuint_x86_64.h | 1146 ++++
.../contrib/ttmath/ttmathuint_x86_64_msvc.asm | 548 ++
.../geometry/extensions/contrib/ttmath_stub.hpp | 293 +
.../extensions/geometries/quantity_point.hpp | 134 +
.../geometry/extensions/gis/geographic/core/cs.hpp | 81 +
.../extensions/gis/geographic/detail/ellipsoid.hpp | 65 +
.../gis/geographic/strategies/andoyer.hpp | 224 +
.../geographic/strategies/area_huiller_earth.hpp | 64 +
.../geographic/strategies/distance_cross_track.hpp | 72 +
.../gis/geographic/strategies/dms_parser.hpp | 267 +
.../gis/geographic/strategies/vincenty.hpp | 262 +
.../gis/io/shapelib/dbf_write_attribute.hpp | 87 +
.../extensions/gis/io/shapelib/shape_creator.hpp | 155 +
.../extensions/gis/io/shapelib/shape_reader.hpp | 72 +
.../gis/io/shapelib/shp_create_object.hpp | 227 +
.../gis/io/shapelib/shp_create_object_multi.hpp | 147 +
.../extensions/gis/io/shapelib/shp_read_object.hpp | 225 +
.../extensions/gis/io/veshape/write_veshape.hpp | 281 +
.../extensions/gis/io/wkb/detail/endian.hpp | 262 +
.../geometry/extensions/gis/io/wkb/detail/ogc.hpp | 86 +
.../extensions/gis/io/wkb/detail/parser.hpp | 315 +
.../geometry/extensions/gis/io/wkb/read_wkb.hpp | 108 +
.../geometry/extensions/gis/io/wkb/utility.hpp | 92 +
.../geometry/extensions/gis/io/wkt/read_wkt.hpp | 68 +
.../geometry/extensions/gis/io/wkt/readme.txt | 15 +
.../geometry/extensions/gis/io/wkt/stream_wkt.hpp | 46 +
src/boost/geometry/extensions/gis/io/wkt/wkt.hpp | 32 +
.../geometry/extensions/gis/io/wkt/write_wkt.hpp | 44 +
.../extensions/gis/latlong/detail/graticule.hpp | 238 +
.../geometry/extensions/gis/latlong/latlong.hpp | 54 +
.../geometry/extensions/gis/latlong/point_ll.hpp | 269 +
.../geometry/extensions/gis/projections/epsg.hpp | 3568 ++++++++++++
.../extensions/gis/projections/epsg_traits.hpp | 43 +
.../extensions/gis/projections/factory.hpp | 255 +
.../extensions/gis/projections/impl/aasincos.hpp | 107 +
.../extensions/gis/projections/impl/adjlon.hpp | 73 +
.../gis/projections/impl/base_dynamic.hpp | 106 +
.../gis/projections/impl/base_static.hpp | 105 +
.../gis/projections/impl/factory_entry.hpp | 43 +
.../gis/projections/impl/function_overloads.hpp | 35 +
.../extensions/gis/projections/impl/pj_auth.hpp | 85 +
.../gis/projections/impl/pj_datum_set.hpp | 167 +
.../extensions/gis/projections/impl/pj_datums.hpp | 106 +
.../extensions/gis/projections/impl/pj_ell_set.hpp | 155 +
.../extensions/gis/projections/impl/pj_ellps.hpp | 93 +
.../extensions/gis/projections/impl/pj_fwd.hpp | 98 +
.../extensions/gis/projections/impl/pj_gauss.hpp | 130 +
.../extensions/gis/projections/impl/pj_init.hpp | 301 +
.../extensions/gis/projections/impl/pj_inv.hpp | 80 +
.../extensions/gis/projections/impl/pj_mlfn.hpp | 111 +
.../extensions/gis/projections/impl/pj_msfn.hpp | 54 +
.../extensions/gis/projections/impl/pj_param.hpp | 155 +
.../extensions/gis/projections/impl/pj_phi2.hpp | 73 +
.../extensions/gis/projections/impl/pj_qsfn.hpp | 84 +
.../extensions/gis/projections/impl/pj_tsfn.hpp | 54 +
.../extensions/gis/projections/impl/pj_units.hpp | 75 +
.../extensions/gis/projections/impl/pj_zpoly1.hpp | 100 +
.../extensions/gis/projections/impl/proj_mdist.hpp | 137 +
.../extensions/gis/projections/impl/projects.hpp | 184 +
.../extensions/gis/projections/parameters.hpp | 65 +
.../extensions/gis/projections/proj/aea.hpp | 525 ++
.../extensions/gis/projections/proj/aeqd.hpp | 454 ++
.../extensions/gis/projections/proj/airy.hpp | 217 +
.../extensions/gis/projections/proj/aitoff.hpp | 210 +
.../extensions/gis/projections/proj/august.hpp | 141 +
.../extensions/gis/projections/proj/bacon.hpp | 238 +
.../extensions/gis/projections/proj/bipc.hpp | 253 +
.../extensions/gis/projections/proj/boggs.hpp | 154 +
.../extensions/gis/projections/proj/bonne.hpp | 246 +
.../extensions/gis/projections/proj/cass.hpp | 465 ++
.../extensions/gis/projections/proj/cc.hpp | 145 +
.../extensions/gis/projections/proj/cea.hpp | 224 +
.../extensions/gis/projections/proj/chamb.hpp | 242 +
.../extensions/gis/projections/proj/collg.hpp | 152 +
.../extensions/gis/projections/proj/crast.hpp | 144 +
.../extensions/gis/projections/proj/denoy.hpp | 140 +
.../extensions/gis/projections/proj/eck1.hpp | 140 +
.../extensions/gis/projections/proj/eck2.hpp | 151 +
.../extensions/gis/projections/proj/eck3.hpp | 286 +
.../extensions/gis/projections/proj/eck4.hpp | 167 +
.../extensions/gis/projections/proj/eck5.hpp | 141 +
.../extensions/gis/projections/proj/eqc.hpp | 146 +
.../extensions/gis/projections/proj/eqdc.hpp | 212 +
.../extensions/gis/projections/proj/fahey.hpp | 140 +
.../extensions/gis/projections/proj/fouc_s.hpp | 167 +
.../extensions/gis/projections/proj/gall.hpp | 142 +
.../extensions/gis/projections/proj/geocent.hpp | 143 +
.../extensions/gis/projections/proj/geos.hpp | 280 +
.../extensions/gis/projections/proj/gins8.hpp | 140 +
.../extensions/gis/projections/proj/gn_sinu.hpp | 380 ++
.../extensions/gis/projections/proj/gnom.hpp | 227 +
.../extensions/gis/projections/proj/goode.hpp | 160 +
.../extensions/gis/projections/proj/gstmerc.hpp | 176 +
.../extensions/gis/projections/proj/hammer.hpp | 152 +
.../extensions/gis/projections/proj/hatano.hpp | 173 +
.../extensions/gis/projections/proj/imw_p.hpp | 281 +
.../extensions/gis/projections/proj/krovak.hpp | 338 ++
.../extensions/gis/projections/proj/labrd.hpp | 231 +
.../extensions/gis/projections/proj/laea.hpp | 391 ++
.../extensions/gis/projections/proj/lagrng.hpp | 158 +
.../extensions/gis/projections/proj/larr.hpp | 134 +
.../extensions/gis/projections/proj/lask.hpp | 148 +
.../extensions/gis/projections/proj/latlong.hpp | 282 +
.../extensions/gis/projections/proj/lcc.hpp | 249 +
.../extensions/gis/projections/proj/lcca.hpp | 191 +
.../extensions/gis/projections/proj/loxim.hpp | 164 +
.../extensions/gis/projections/proj/lsat.hpp | 299 +
.../extensions/gis/projections/proj/mbt_fps.hpp | 161 +
.../extensions/gis/projections/proj/mbtfpp.hpp | 155 +
.../extensions/gis/projections/proj/mbtfpq.hpp | 170 +
.../extensions/gis/projections/proj/merc.hpp | 213 +
.../extensions/gis/projections/proj/mill.hpp | 138 +
.../extensions/gis/projections/proj/mod_ster.hpp | 474 ++
.../extensions/gis/projections/proj/moll.hpp | 262 +
.../extensions/gis/projections/proj/nell.hpp | 154 +
.../extensions/gis/projections/proj/nell_h.hpp | 153 +
.../extensions/gis/projections/proj/nocol.hpp | 160 +
.../extensions/gis/projections/proj/nsper.hpp | 317 +
.../extensions/gis/projections/proj/nzmg.hpp | 196 +
.../extensions/gis/projections/proj/ob_tran.hpp | 318 +
.../extensions/gis/projections/proj/ocea.hpp | 189 +
.../extensions/gis/projections/proj/oea.hpp | 181 +
.../extensions/gis/projections/proj/omerc.hpp | 295 +
.../extensions/gis/projections/proj/ortho.hpp | 219 +
.../extensions/gis/projections/proj/poly.hpp | 266 +
.../extensions/gis/projections/proj/putp2.hpp | 163 +
.../extensions/gis/projections/proj/putp3.hpp | 197 +
.../extensions/gis/projections/proj/putp4p.hpp | 201 +
.../extensions/gis/projections/proj/putp5.hpp | 198 +
.../extensions/gis/projections/proj/putp6.hpp | 223 +
.../extensions/gis/projections/proj/robin.hpp | 232 +
.../extensions/gis/projections/proj/rouss.hpp | 211 +
.../extensions/gis/projections/proj/rpoly.hpp | 158 +
.../extensions/gis/projections/proj/sconics.hpp | 511 ++
.../extensions/gis/projections/proj/somerc.hpp | 188 +
.../extensions/gis/projections/proj/stere.hpp | 451 ++
.../extensions/gis/projections/proj/sterea.hpp | 381 ++
.../extensions/gis/projections/proj/sts.hpp | 294 +
.../extensions/gis/projections/proj/tcc.hpp | 142 +
.../extensions/gis/projections/proj/tcea.hpp | 149 +
.../extensions/gis/projections/proj/tmerc.hpp | 458 ++
.../extensions/gis/projections/proj/tpeqd.hpp | 198 +
.../extensions/gis/projections/proj/urm5.hpp | 149 +
.../extensions/gis/projections/proj/urmfps.hpp | 205 +
.../extensions/gis/projections/proj/vandg.hpp | 201 +
.../extensions/gis/projections/proj/vandg2.hpp | 205 +
.../extensions/gis/projections/proj/vandg4.hpp | 163 +
.../extensions/gis/projections/proj/wag2.hpp | 144 +
.../extensions/gis/projections/proj/wag3.hpp | 148 +
.../extensions/gis/projections/proj/wag7.hpp | 137 +
.../extensions/gis/projections/proj/wink1.hpp | 145 +
.../extensions/gis/projections/proj/wink2.hpp | 159 +
.../projections/project_inverse_transformer.hpp | 73 +
.../gis/projections/project_transformer.hpp | 65 +
.../extensions/gis/projections/projection.hpp | 65 +
.../geometry/extensions/index/rtree/helpers.hpp | 68 +
.../geometry/extensions/index/rtree/rtree.hpp | 774 +++
.../geometry/extensions/index/rtree/rtree_leaf.hpp | 253 +
.../geometry/extensions/index/rtree/rtree_node.hpp | 493 ++
.../geometry/extensions/io/svg/svg_mapper.hpp | 347 ++
src/boost/geometry/extensions/io/svg/write_svg.hpp | 272 +
.../geometry/extensions/io/svg/write_svg_multi.hpp | 78 +
.../extensions/iterators/circular_iterator.hpp | 121 +
.../extensions/iterators/section_iterators.hpp | 233 +
.../iterators/segment_returning_iterator.hpp | 139 +
.../extensions/multi/algorithms/dissolve.hpp | 99 +
.../extensions/nsphere/algorithms/append.hpp | 45 +
.../extensions/nsphere/algorithms/area.hpp | 82 +
.../extensions/nsphere/algorithms/assign.hpp | 93 +
.../extensions/nsphere/algorithms/clear.hpp | 47 +
.../extensions/nsphere/algorithms/envelope.hpp | 83 +
.../extensions/nsphere/algorithms/num_points.hpp | 46 +
.../extensions/nsphere/algorithms/within.hpp | 209 +
.../geometry/extensions/nsphere/core/access.hpp | 52 +
.../extensions/nsphere/core/geometry_id.hpp | 47 +
.../geometry/extensions/nsphere/core/radius.hpp | 160 +
.../extensions/nsphere/core/replace_point_type.hpp | 48 +
.../geometry/extensions/nsphere/core/tags.hpp | 29 +
.../nsphere/core/topological_dimension.hpp | 50 +
.../nsphere/geometries/concepts/check.hpp | 42 +
.../geometries/concepts/nsphere_concept.hpp | 122 +
.../extensions/nsphere/geometries/nsphere.hpp | 144 +
src/boost/geometry/extensions/nsphere/nsphere.hpp | 37 +
.../geometry/extensions/strategies/buffer.hpp | 396 ++
.../extensions/strategies/buffer_join_round.hpp | 176 +
.../geometry/extensions/strategies/buffer_side.hpp | 31 +
src/boost/geometry/extensions/strategies/parse.hpp | 41 +
.../geometry/extensions/util/get_cs_as_radian.hpp | 55 +
.../extensions/util/replace_point_type.hpp | 98 +
.../geometry/extensions/views/enveloped_view.hpp | 126 +
.../geometry/extensions/views/section_view.hpp | 73 +
.../geometry/geometries/adapted/boost_array.hpp | 120 +
.../geometry/geometries/adapted/boost_fusion.hpp | 172 +
.../geometry/geometries/adapted/boost_polygon.hpp | 18 +
.../geometries/adapted/boost_polygon/box.hpp | 141 +
.../adapted/boost_polygon/hole_iterator.hpp | 84 +
.../adapted/boost_polygon/holes_proxy.hpp | 204 +
.../geometries/adapted/boost_polygon/point.hpp | 102 +
.../geometries/adapted/boost_polygon/polygon.hpp | 111 +
.../geometries/adapted/boost_polygon/ring.hpp | 163 +
.../adapted/boost_polygon/ring_proxy.hpp | 301 +
.../adapted/boost_range/adjacent_filtered.hpp | 40 +
.../geometries/adapted/boost_range/filtered.hpp | 40 +
.../geometries/adapted/boost_range/reversed.hpp | 40 +
.../geometries/adapted/boost_range/sliced.hpp | 36 +
.../geometries/adapted/boost_range/strided.hpp | 36 +
.../geometries/adapted/boost_range/uniqued.hpp | 40 +
.../geometry/geometries/adapted/boost_tuple.hpp | 109 +
src/boost/geometry/geometries/adapted/c_array.hpp | 111 +
.../geometries/adapted/std_pair_as_segment.hpp | 98 +
src/boost/geometry/geometries/box.hpp | 134 +
.../geometry/geometries/concepts/box_concept.hpp | 136 +
src/boost/geometry/geometries/concepts/check.hpp | 171 +
.../geometries/concepts/linestring_concept.hpp | 125 +
.../geometry/geometries/concepts/point_concept.hpp | 176 +
.../geometries/concepts/polygon_concept.hpp | 135 +
.../geometry/geometries/concepts/ring_concept.hpp | 99 +
.../geometries/concepts/segment_concept.hpp | 135 +
src/boost/geometry/geometries/geometries.hpp | 25 +
src/boost/geometry/geometries/linestring.hpp | 95 +
src/boost/geometry/geometries/point.hpp | 178 +
src/boost/geometry/geometries/point_xy.hpp | 128 +
src/boost/geometry/geometries/polygon.hpp | 319 +
src/boost/geometry/geometries/register/box.hpp | 179 +
.../geometry/geometries/register/linestring.hpp | 60 +
src/boost/geometry/geometries/register/point.hpp | 173 +
src/boost/geometry/geometries/register/ring.hpp | 60 +
src/boost/geometry/geometries/register/segment.hpp | 129 +
src/boost/geometry/geometries/ring.hpp | 153 +
src/boost/geometry/geometries/segment.hpp | 203 +
src/boost/geometry/geometry.hpp | 91 +
src/boost/geometry/io/dsv/write.hpp | 375 ++
src/boost/geometry/io/io.hpp | 58 +
src/boost/geometry/io/wkt/detail/prefix.hpp | 45 +
src/boost/geometry/io/wkt/detail/wkt_multi.hpp | 57 +
src/boost/geometry/io/wkt/iomanip.hpp | 46 +
src/boost/geometry/io/wkt/read.hpp | 686 +++
src/boost/geometry/io/wkt/stream.hpp | 40 +
src/boost/geometry/io/wkt/wkt.hpp | 25 +
src/boost/geometry/io/wkt/write.hpp | 376 ++
src/boost/geometry/iterators/base.hpp | 70 +
src/boost/geometry/iterators/closing_iterator.hpp | 157 +
.../geometry/iterators/ever_circling_iterator.hpp | 212 +
src/boost/geometry/multi/algorithms/append.hpp | 52 +
src/boost/geometry/multi/algorithms/area.hpp | 57 +
src/boost/geometry/multi/algorithms/centroid.hpp | 178 +
src/boost/geometry/multi/algorithms/clear.hpp | 43 +
src/boost/geometry/multi/algorithms/convert.hpp | 128 +
src/boost/geometry/multi/algorithms/correct.hpp | 66 +
src/boost/geometry/multi/algorithms/covered_by.hpp | 70 +
.../multi/algorithms/detail/for_each_range.hpp | 86 +
.../geometry/multi/algorithms/detail/modify.hpp | 53 +
.../algorithms/detail/modify_with_predicate.hpp | 52 +
.../geometry/multi/algorithms/detail/multi_sum.hpp | 58 +
.../detail/overlay/copy_segment_point.hpp | 101 +
.../algorithms/detail/overlay/copy_segments.hpp | 104 +
.../multi/algorithms/detail/overlay/get_ring.hpp | 54 +
.../multi/algorithms/detail/overlay/get_turns.hpp | 111 +
.../algorithms/detail/overlay/select_rings.hpp | 62 +
.../algorithms/detail/overlay/self_turn_points.hpp | 56 +
.../multi/algorithms/detail/point_on_border.hpp | 95 +
.../detail/sections/range_by_section.hpp | 90 +
.../algorithms/detail/sections/sectionalize.hpp | 95 +
src/boost/geometry/multi/algorithms/distance.hpp | 157 +
src/boost/geometry/multi/algorithms/envelope.hpp | 117 +
src/boost/geometry/multi/algorithms/equals.hpp | 70 +
src/boost/geometry/multi/algorithms/for_each.hpp | 129 +
.../geometry/multi/algorithms/intersection.hpp | 438 ++
src/boost/geometry/multi/algorithms/length.hpp | 57 +
.../geometry/multi/algorithms/num_geometries.hpp | 51 +
.../multi/algorithms/num_interior_rings.hpp | 61 +
src/boost/geometry/multi/algorithms/num_points.hpp | 81 +
src/boost/geometry/multi/algorithms/perimeter.hpp | 56 +
src/boost/geometry/multi/algorithms/reverse.hpp | 69 +
src/boost/geometry/multi/algorithms/simplify.hpp | 117 +
src/boost/geometry/multi/algorithms/transform.hpp | 102 +
src/boost/geometry/multi/algorithms/unique.hpp | 102 +
src/boost/geometry/multi/algorithms/within.hpp | 104 +
src/boost/geometry/multi/core/closure.hpp | 58 +
src/boost/geometry/multi/core/geometry_id.hpp | 56 +
src/boost/geometry/multi/core/interior_rings.hpp | 55 +
src/boost/geometry/multi/core/is_areal.hpp | 43 +
src/boost/geometry/multi/core/point_order.hpp | 57 +
src/boost/geometry/multi/core/point_type.hpp | 64 +
src/boost/geometry/multi/core/ring_type.hpp | 66 +
src/boost/geometry/multi/core/tags.hpp | 71 +
.../geometry/multi/core/topological_dimension.hpp | 52 +
.../geometry/multi/geometries/concepts/check.hpp | 83 +
.../concepts/multi_linestring_concept.hpp | 86 +
.../geometries/concepts/multi_point_concept.hpp | 85 +
.../geometries/concepts/multi_polygon_concept.hpp | 86 +
.../geometry/multi/geometries/multi_geometries.hpp | 21 +
.../geometry/multi/geometries/multi_linestring.hpp | 80 +
.../geometry/multi/geometries/multi_point.hpp | 94 +
.../geometry/multi/geometries/multi_polygon.hpp | 78 +
.../multi/geometries/register/multi_linestring.hpp | 59 +
.../multi/geometries/register/multi_point.hpp | 59 +
.../multi/geometries/register/multi_polygon.hpp | 59 +
src/boost/geometry/multi/io/dsv/write.hpp | 83 +
src/boost/geometry/multi/io/wkt/detail/prefix.hpp | 51 +
src/boost/geometry/multi/io/wkt/read.hpp | 167 +
src/boost/geometry/multi/io/wkt/wkt.hpp | 20 +
src/boost/geometry/multi/io/wkt/write.hpp | 108 +
src/boost/geometry/multi/multi.hpp | 77 +
.../strategies/cartesian/centroid_average.hpp | 116 +
src/boost/geometry/multi/util/write_dsv.hpp | 78 +
.../geometry/multi/views/detail/range_type.hpp | 62 +
src/boost/geometry/policies/compare.hpp | 242 +
src/boost/geometry/policies/relate/de9im.hpp | 177 +
src/boost/geometry/policies/relate/direction.hpp | 362 ++
.../policies/relate/intersection_points.hpp | 165 +
.../relate/intersection_points_determinant.hpp | 176 +
.../policies/relate/intersection_points_slope.hpp | 213 +
src/boost/geometry/policies/relate/tupled.hpp | 175 +
.../strategies/agnostic/hull_graham_andrew.hpp | 384 ++
.../strategies/agnostic/point_in_box_by_side.hpp | 151 +
.../agnostic/point_in_poly_oriented_winding.hpp | 208 +
.../strategies/agnostic/point_in_poly_winding.hpp | 232 +
.../agnostic/simplify_douglas_peucker.hpp | 229 +
src/boost/geometry/strategies/area.hpp | 50 +
.../strategies/cartesian/area_surveyor.hpp | 134 +
.../geometry/strategies/cartesian/box_in_box.hpp | 176 +
.../strategies/cartesian/cart_intersect.hpp | 738 +++
.../cartesian/centroid_bashein_detmer.hpp | 242 +
.../cartesian/centroid_weighted_length.hpp | 144 +
.../cartesian/distance_projected_point.hpp | 319 +
.../strategies/cartesian/distance_pythagoras.hpp | 349 ++
.../geometry/strategies/cartesian/point_in_box.hpp | 172 +
.../cartesian/point_in_poly_crossings_multiply.hpp | 124 +
.../cartesian/point_in_poly_franklin.hpp | 118 +
.../strategies/cartesian/side_by_triangle.hpp | 121 +
src/boost/geometry/strategies/centroid.hpp | 72 +
src/boost/geometry/strategies/compare.hpp | 172 +
.../geometry/strategies/concepts/area_concept.hpp | 75 +
.../strategies/concepts/centroid_concept.hpp | 78 +
.../strategies/concepts/convex_hull_concept.hpp | 75 +
.../strategies/concepts/distance_concept.hpp | 206 +
.../concepts/segment_intersect_concept.hpp | 78 +
.../strategies/concepts/simplify_concept.hpp | 109 +
.../strategies/concepts/within_concept.hpp | 291 +
src/boost/geometry/strategies/convex_hull.hpp | 47 +
src/boost/geometry/strategies/covered_by.hpp | 72 +
.../geometry/strategies/default_area_result.hpp | 51 +
.../strategies/default_distance_result.hpp | 50 +
.../geometry/strategies/default_length_result.hpp | 46 +
src/boost/geometry/strategies/distance.hpp | 135 +
src/boost/geometry/strategies/intersection.hpp | 93 +
.../geometry/strategies/intersection_result.hpp | 174 +
src/boost/geometry/strategies/side.hpp | 55 +
src/boost/geometry/strategies/side_info.hpp | 166 +
.../geometry/strategies/spherical/area_huiller.hpp | 202 +
.../strategies/spherical/compare_circular.hpp | 152 +
.../strategies/spherical/distance_cross_track.hpp | 349 ++
.../strategies/spherical/distance_haversine.hpp | 330 ++
.../strategies/spherical/side_by_cross_track.hpp | 100 +
src/boost/geometry/strategies/spherical/ssf.hpp | 136 +
src/boost/geometry/strategies/strategies.hpp | 59 +
.../geometry/strategies/strategy_transform.hpp | 504 ++
src/boost/geometry/strategies/tags.hpp | 41 +
src/boost/geometry/strategies/transform.hpp | 63 +
.../strategies/transform/inverse_transformer.hpp | 78 +
.../strategies/transform/map_transformer.hpp | 165 +
.../strategies/transform/matrix_transformers.hpp | 422 ++
src/boost/geometry/strategies/within.hpp | 71 +
src/boost/geometry/util/add_const_if_c.hpp | 56 +
src/boost/geometry/util/calculation_type.hpp | 176 +
src/boost/geometry/util/closure_as_bool.hpp | 46 +
src/boost/geometry/util/coordinate_cast.hpp | 55 +
src/boost/geometry/util/for_each_coordinate.hpp | 94 +
src/boost/geometry/util/math.hpp | 222 +
src/boost/geometry/util/order_as_direction.hpp | 46 +
src/boost/geometry/util/parameter_type_of.hpp | 75 +
src/boost/geometry/util/promote_floating_point.hpp | 50 +
src/boost/geometry/util/rational.hpp | 179 +
src/boost/geometry/util/readme.txt | 17 +
.../geometry/util/select_calculation_type.hpp | 57 +
src/boost/geometry/util/select_coordinate_type.hpp | 45 +
src/boost/geometry/util/select_most_precise.hpp | 162 +
src/boost/geometry/util/write_dsv.hpp | 396 ++
src/boost/geometry/views/box_view.hpp | 114 +
src/boost/geometry/views/closeable_view.hpp | 100 +
src/boost/geometry/views/detail/points_view.hpp | 141 +
src/boost/geometry/views/detail/range_type.hpp | 106 +
src/boost/geometry/views/identity_view.hpp | 53 +
src/boost/geometry/views/reversible_view.hpp | 74 +
src/boost/geometry/views/segment_view.hpp | 100 +
src/boost/range/adaptor/adjacent_filtered.hpp | 238 +
src/boost/range/adaptor/argument_fwd.hpp | 80 +
src/boost/range/adaptor/copied.hpp | 58 +
src/boost/range/adaptor/define_adaptor.hpp | 109 +
src/boost/range/adaptor/filtered.hpp | 101 +
src/boost/range/adaptor/indexed.hpp | 156 +
src/boost/range/adaptor/indirected.hpp | 88 +
src/boost/range/adaptor/map.hpp | 187 +
src/boost/range/adaptor/replaced.hpp | 134 +
src/boost/range/adaptor/replaced_if.hpp | 136 +
src/boost/range/adaptor/reversed.hpp | 90 +
src/boost/range/adaptor/sliced.hpp | 82 +
src/boost/range/adaptor/strided.hpp | 350 ++
src/boost/range/adaptor/tokenized.hpp | 137 +
src/boost/range/adaptor/transformed.hpp | 104 +
src/boost/range/adaptor/type_erased.hpp | 184 +
src/boost/range/adaptor/uniqued.hpp | 90 +
src/boost/range/adaptors.hpp | 30 +
src/boost/range/algorithm.hpp | 104 +
src/boost/range/algorithm/adjacent_find.hpp | 125 +
src/boost/range/algorithm/binary_search.hpp | 49 +
src/boost/range/algorithm/copy.hpp | 41 +
src/boost/range/algorithm/copy_backward.hpp | 43 +
src/boost/range/algorithm/count.hpp | 50 +
src/boost/range/algorithm/count_if.hpp | 51 +
src/boost/range/algorithm/equal.hpp | 198 +
src/boost/range/algorithm/equal_range.hpp | 80 +
src/boost/range/algorithm/fill.hpp | 49 +
src/boost/range/algorithm/fill_n.hpp | 53 +
src/boost/range/algorithm/find.hpp | 80 +
src/boost/range/algorithm/find_end.hpp | 152 +
src/boost/range/algorithm/find_first_of.hpp | 155 +
src/boost/range/algorithm/find_if.hpp | 81 +
src/boost/range/algorithm/for_each.hpp | 109 +
src/boost/range/algorithm/generate.hpp | 49 +
src/boost/range/algorithm/heap_algorithm.hpp | 194 +
src/boost/range/algorithm/inplace_merge.hpp | 74 +
.../range/algorithm/lexicographical_compare.hpp | 58 +
src/boost/range/algorithm/lower_bound.hpp | 124 +
src/boost/range/algorithm/max_element.hpp | 115 +
src/boost/range/algorithm/merge.hpp | 61 +
src/boost/range/algorithm/min_element.hpp | 115 +
src/boost/range/algorithm/mismatch.hpp | 195 +
src/boost/range/algorithm/nth_element.hpp | 74 +
src/boost/range/algorithm/partial_sort.hpp | 76 +
src/boost/range/algorithm/partial_sort_copy.hpp | 82 +
src/boost/range/algorithm/partition.hpp | 74 +
src/boost/range/algorithm/permutation.hpp | 108 +
src/boost/range/algorithm/random_shuffle.hpp | 68 +
src/boost/range/algorithm/remove.hpp | 74 +
src/boost/range/algorithm/remove_copy.hpp | 44 +
src/boost/range/algorithm/remove_copy_if.hpp | 38 +
src/boost/range/algorithm/remove_if.hpp | 75 +
src/boost/range/algorithm/replace.hpp | 53 +
src/boost/range/algorithm/replace_copy.hpp | 42 +
src/boost/range/algorithm/replace_copy_if.hpp | 46 +
src/boost/range/algorithm/replace_if.hpp | 54 +
src/boost/range/algorithm/reverse.hpp | 50 +
src/boost/range/algorithm/reverse_copy.hpp | 40 +
src/boost/range/algorithm/rotate.hpp | 51 +
src/boost/range/algorithm/rotate_copy.hpp | 44 +
src/boost/range/algorithm/search.hpp | 134 +
src/boost/range/algorithm/search_n.hpp | 360 ++
src/boost/range/algorithm/set_algorithm.hpp | 198 +
src/boost/range/algorithm/sort.hpp | 68 +
src/boost/range/algorithm/stable_partition.hpp | 73 +
src/boost/range/algorithm/stable_sort.hpp | 68 +
src/boost/range/algorithm/swap_ranges.hpp | 132 +
src/boost/range/algorithm/transform.hpp | 97 +
src/boost/range/algorithm/unique.hpp | 107 +
src/boost/range/algorithm/unique_copy.hpp | 51 +
src/boost/range/algorithm/upper_bound.hpp | 127 +
src/boost/range/algorithm_ext.hpp | 28 +
src/boost/range/algorithm_ext/copy_n.hpp | 53 +
src/boost/range/algorithm_ext/erase.hpp | 61 +
src/boost/range/algorithm_ext/for_each.hpp | 86 +
src/boost/range/algorithm_ext/insert.hpp | 42 +
src/boost/range/algorithm_ext/iota.hpp | 54 +
src/boost/range/algorithm_ext/is_sorted.hpp | 57 +
src/boost/range/algorithm_ext/overwrite.hpp | 84 +
src/boost/range/algorithm_ext/push_back.hpp | 40 +
src/boost/range/algorithm_ext/push_front.hpp | 40 +
src/boost/range/any_range.hpp | 205 +
src/boost/range/as_array.hpp | 45 +
src/boost/range/as_literal.hpp | 127 +
src/boost/range/atl.hpp | 733 +++
src/boost/range/begin.hpp | 143 +
src/boost/range/category.hpp | 29 +
src/boost/range/combine.hpp | 304 +
src/boost/range/concepts.hpp | 366 ++
src/boost/range/config.hpp | 54 +
src/boost/range/const_iterator.hpp | 67 +
src/boost/range/const_reverse_iterator.hpp | 32 +
src/boost/range/counting_range.hpp | 66 +
src/boost/range/detail/any_iterator.hpp | 586 ++
src/boost/range/detail/any_iterator_buffer.hpp | 117 +
src/boost/range/detail/any_iterator_interface.hpp | 258 +
src/boost/range/detail/any_iterator_wrapper.hpp | 590 ++
src/boost/range/detail/as_literal.hpp | 33 +
src/boost/range/detail/begin.hpp | 94 +
src/boost/range/detail/collection_traits.hpp | 266 +
.../range/detail/collection_traits_detail.hpp | 621 ++
src/boost/range/detail/common.hpp | 117 +
src/boost/range/detail/const_iterator.hpp | 71 +
.../range/detail/demote_iterator_traversal_tag.hpp | 91 +
src/boost/range/detail/detail_str.hpp | 376 ++
src/boost/range/detail/difference_type.hpp | 121 +
src/boost/range/detail/empty.hpp | 120 +
src/boost/range/detail/end.hpp | 101 +
src/boost/range/detail/extract_optional_type.hpp | 52 +
src/boost/range/detail/implementation_help.hpp | 103 +
src/boost/range/detail/iterator.hpp | 78 +
src/boost/range/detail/join_iterator.hpp | 344 ++
src/boost/range/detail/microsoft.hpp | 931 +++
src/boost/range/detail/misc_concept.hpp | 33 +
src/boost/range/detail/range_return.hpp | 180 +
src/boost/range/detail/remove_extent.hpp | 157 +
src/boost/range/detail/safe_bool.hpp | 72 +
src/boost/range/detail/sfinae.hpp | 77 +
src/boost/range/detail/size.hpp | 159 +
src/boost/range/detail/size_type.hpp | 55 +
src/boost/range/detail/sizer.hpp | 35 +
src/boost/range/detail/str_types.hpp | 38 +
src/boost/range/detail/value_type.hpp | 72 +
src/boost/range/detail/vc6/end.hpp | 170 +
src/boost/range/detail/vc6/size.hpp | 166 +
src/boost/range/difference_type.hpp | 29 +
src/boost/range/distance.hpp | 34 +
src/boost/range/empty.hpp | 34 +
src/boost/range/end.hpp | 136 +
src/boost/range/functions.hpp | 27 +
src/boost/range/has_range_iterator.hpp | 62 +
src/boost/range/irange.hpp | 230 +
src/boost/range/istream_range.hpp | 37 +
src/boost/range/iterator.hpp | 72 +
src/boost/range/iterator_range.hpp | 16 +
src/boost/range/iterator_range_core.hpp | 650 +++
src/boost/range/iterator_range_io.hpp | 93 +
src/boost/range/join.hpp | 91 +
src/boost/range/metafunctions.hpp | 31 +
src/boost/range/mfc.hpp | 984 ++++
src/boost/range/mutable_iterator.hpp | 67 +
src/boost/range/numeric.hpp | 118 +
src/boost/range/pointer.hpp | 29 +
src/boost/range/rbegin.hpp | 65 +
src/boost/range/reference.hpp | 29 +
src/boost/range/rend.hpp | 65 +
src/boost/range/result_iterator.hpp | 33 +
src/boost/range/reverse_iterator.hpp | 40 +
src/boost/range/reverse_result_iterator.hpp | 32 +
src/boost/range/size.hpp | 52 +
src/boost/range/size_type.hpp | 89 +
src/boost/range/sub_range.hpp | 182 +
src/boost/range/value_type.hpp | 34 +
src/common/ColourTableDefinitionCompute.cc | 4 +-
src/common/GeoRectangularProjection.cc | 6 +-
src/common/MagicsCalls.cc | 6 +-
src/common/Matrix.cc | 11 +-
src/common/MatrixHandler.h | 20 +-
src/common/Proj4Projection.cc | 14 +-
src/decoders/CMakeLists.txt | 4 +-
src/decoders/GribDecoder.cc | 2 +-
src/decoders/InputMatrix.cc | 4 +-
src/decoders/InputMatrixInterpretor.cc | 9 +-
src/decoders/Netcdf.cc | 321 ++
src/decoders/{NetcdfData.h => Netcdf.h} | 274 +-
src/decoders/NetcdfData.cc | 329 --
src/decoders/NetcdfGeoMatrixInterpretor.cc | 9 +-
src/decoders/NetcdfGeopointsInterpretor.cc | 11 +-
src/decoders/NetcdfInterpretor.cc | 24 +-
src/decoders/NetcdfMatrixInterpretor.cc | 24 +-
src/decoders/NetcdfOrcaInterpretor.cc | 4 +-
src/decoders/NetcdfVectorInterpretor.cc | 6 +-
src/decoders/ShapeDecoder.cc | 2 +
src/drivers/BaseDriver.cc | 2 +-
src/drivers/MgQ/MgQLayerItem.cc | 3 -
src/drivers/MgQ/MgQPlotScene.cc | 6 +-
src/drivers/MgQ/MgQSceneItem.cc | 11 +-
src/libMagWrapper/MagPlus.cc | 92 +-
src/libMagWrapper/MagPlus.h | 8 -
src/params/Axis.xml | 2 +-
src/params/Boundaries.xml | 2 +-
src/visualisers/AutomaticContourMethod.h | 11 +-
src/visualisers/Axis.cc | 6 +-
src/visualisers/CalcStreamlines.cc | 7 +-
src/visualisers/Coastlines.cc | 5 +-
src/visualisers/EpsGraph.cc | 9 +-
src/visualisers/IsoPlot.cc | 5 +-
src/visualisers/SymbolAdvancedTableMode.cc | 14 +-
src/visualisers/SymbolAdvancedTableMode.h | 20 +-
src/visualisers/SymbolMode.cc | 5 -
src/visualisers/SymbolMode.h | 8 +-
src/visualisers/SymbolPlotting.cc | 9 +-
test/bufr.py | 2 +-
test/cairo.py | 2 +-
test/grib.py | 2 +-
tools/xml2mv.py | 40 +-
786 files changed, 140352 insertions(+), 7510 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 983fbcd..6ad0e2d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -91,7 +91,7 @@ ecbuild_add_option( FEATURE GEOTIFF
ecbuild_add_option( FEATURE NETCDF
DEFAULT ON
DESCRIPTION "enable netcdf support"
- REQUIRED_PACKAGES "NetCDF 4 COMPONENTS C" )
+ REQUIRED_PACKAGES "NetCDF 4 COMPONENTS C CXX" )
ecbuild_add_option( FEATURE SPOT
DEFAULT OFF
@@ -101,7 +101,7 @@ ecbuild_add_option( FEATURE SPOT
ecbuild_add_option( FEATURE PYTHON
DEFAULT ON
DESCRIPTION "enable python interface"
- REQUIRED_PACKAGES "Python NO_LIBS" NumPy )
+ REQUIRED_PACKAGES "Python NO_LIBS" SWIG NumPy )
ecbuild_add_option( FEATURE FORTRAN
DEFAULT ON
@@ -142,7 +142,7 @@ set( MAGICS_EXCEPTION "ON" )
set( MAGICS_SITE "ecmwf" )
set( MAGICS_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} )
-set( MAGICS_REFERENCE_VERSIONS "2.33.0" )
+set( MAGICS_REFERENCE_VERSIONS "2.34.0" )
set( MAGICS_HTML_ROOT "${CMAKE_BINARY_DIR}/regression/html")
file(MAKE_DIRECTORY ${MAGICS_HTML_ROOT} )
diff --git a/VERSION.cmake b/VERSION.cmake
index 734158f..a6fb9ab 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -6,8 +6,7 @@
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
-set ( metabuilder_version 2.99.0 )
-set ( _version 2.99.0 )
+set ( metabuilder_version 2.34.1 )
if ( MAGICS_BUILD )
set( ${PROJECT_NAME}_VERSION_STR "${metabuilder_version}-${MAGICS_BUILD}" )
diff --git a/magics.sublime-project b/magics.sublime-project
index 07b95f2..30407a8 100644
--- a/magics.sublime-project
+++ b/magics.sublime-project
@@ -7,7 +7,7 @@
],
"build_systems": [
{
- "working_dir": "${project_path}/../../build/magics/debug",
+ "working_dir": "${project_path}/../../build/magics-develop/debug",
"cmd": [
"make"
],
diff --git a/notebook/2t.json b/notebook/2t.json
deleted file mode 100644
index b2de218..0000000
--- a/notebook/2t.json
+++ /dev/null
@@ -1,446 +0,0 @@
-{
- "2t": {
- "control": [
- 286.363555908,
- 295.42590332,
- 288.289245605,
- 283.227111816,
- 284.768005371,
- 298.521240234,
- 289.271118164,
- 282.546447754,
- 282.42364502,
- 290.771759033,
- 285.135772705,
- 280.21282959,
- 282.69833374,
- 294.380523682,
- 289.007141113,
- 285.248535156,
- 287.911773682,
- 298.400360107,
- 291.505340576,
- 287.898681641,
- 289.753204346,
- 297.436523438,
- 294.083251953,
- 288.13772583,
- 289.16204834,
- 293.397827148,
- 288.49017334,
- 283.674133301,
- 284.987060547,
- 296.456176758,
- 290.638092041,
- 286.387756348,
- 286.409423828,
- 292.802185059,
- 285.958343506,
- 279.491577148,
- 281.795806885,
- 295.196777344,
- 287.484191895,
- 283.851043701
- ],
- "hres": [
- 286.47076416,
- 295.495910645,
- 288.691345215,
- 283.233398438,
- 284.709197998,
- 298.904296875,
- 289.790405273,
- 282.804992676,
- 282.675109863,
- 290.824859619,
- 285.316101074,
- 280.453765869,
- 283.255493164,
- 294.719268799,
- 289.027526855,
- 285.48828125,
- 288.530761719,
- 298.677612305,
- 292.673400879,
- 287.894439697,
- 289.864593506,
- 297.076965332,
- 291.796142578,
- 285.934509277,
- 288.623962402,
- 296.004669189,
- 290.774261475,
- 286.00100708,
- 283.262145996,
- 290.297637939,
- 284.291809082,
- 278.563995361,
- 280.591705322,
- 289.775543213,
- 284.149383545,
- 278.752746582,
- 280.501861572,
- 290.652832031,
- 284.741760254,
- 280.484558105
- ],
- "max": [
- 289.032806396,
- 296.861328125,
- 289.512145996,
- 284.101806641,
- 289.76550293,
- 300.050567627,
- 291.680603027,
- 283.86114502,
- 283.660247803,
- 296.359344482,
- 288.169189453,
- 283.256164551,
- 286.525695801,
- 296.944671631,
- 290.775482178,
- 286.897369385,
- 289.295684814,
- 298.850921631,
- 295.217651367,
- 290.919311523,
- 291.373291016,
- 298.837982178,
- 296.096191406,
- 290.9090271,
- 290.739532471,
- 299.005126953,
- 294.404052734,
- 289.256835938,
- 290.398986816,
- 299.747070312,
- 293.180114746,
- 289.155090332,
- 290.383056641,
- 299.298461914,
- 292.229431152,
- 288.717224121,
- 290.339660645,
- 300.006317139,
- 294.085632324,
- 289.090789795
- ],
- "median": [
- 286.492553711,
- 295.472961426,
- 288.296936035,
- 283.457519531,
- 285.196990967,
- 298.145874023,
- 289.156433105,
- 282.541107178,
- 282.453979492,
- 290.914337158,
- 285.315429688,
- 280.618438721,
- 283.02331543,
- 294.633789062,
- 288.966003418,
- 285.464660645,
- 287.969268799,
- 298.135803223,
- 292.146972656,
- 288.518737793,
- 290.059631348,
- 297.408782959,
- 292.117218018,
- 286.862121582,
- 287.110168457,
- 294.837097168,
- 289.279541016,
- 284.571563721,
- 284.963134766,
- 294.609802246,
- 288.487792969,
- 282.523864746,
- 283.477844238,
- 293.718017578,
- 287.233825684,
- 282.069519043,
- 283.33807373,
- 294.140014648,
- 288.05670166,
- 283.841491699
- ],
- "min": [
- 285.867858887,
- 294.534881592,
- 287.052062988,
- 282.311981201,
- 283.788024902,
- 295.57598877,
- 287.221252441,
- 281.044403076,
- 281.52746582,
- 289.333709717,
- 283.824310303,
- 279.032348633,
- 281.638427734,
- 292.612915039,
- 287.003082275,
- 283.887268066,
- 287.184387207,
- 297.371643066,
- 290.119659424,
- 286.563354492,
- 287.72442627,
- 294.573760986,
- 287.503112793,
- 280.882965088,
- 280.308898926,
- 287.464599609,
- 282.296936035,
- 279.178039551,
- 278.161193848,
- 286.75604248,
- 281.435577393,
- 276.856018066,
- 277.591430664,
- 286.144897461,
- 281.967529297,
- 276.480133057,
- 278.220306396,
- 286.531921387,
- 280.869873047,
- 276.132751465
- ],
- "ninety": [
- 287.067626953,
- 296.160705566,
- 289.015014648,
- 283.852111816,
- 288.084716797,
- 299.35055542,
- 290.13848877,
- 283.252319336,
- 282.979125977,
- 292.99130249,
- 286.915008545,
- 281.710571289,
- 284.582366943,
- 295.857971191,
- 290.016967773,
- 286.405334473,
- 288.637695312,
- 298.550750732,
- 292.952758789,
- 289.710998535,
- 290.823974609,
- 298.609436035,
- 294.272766113,
- 289.418334961,
- 290.360168457,
- 297.257873535,
- 291.926208496,
- 287.899597168,
- 288.631103516,
- 297.692474365,
- 291.288970947,
- 287.159759521,
- 289.193817139,
- 297.80065918,
- 291.440429688,
- 287.258117676,
- 289.456665039,
- 298.733337402,
- 291.760681152,
- 288.395141602
- ],
- "seventy_five": [
- 286.817993164,
- 295.803863525,
- 288.567626953,
- 283.697174072,
- 286.263061523,
- 298.804321289,
- 289.830444336,
- 283.040557861,
- 282.692260742,
- 291.551361084,
- 285.960083008,
- 281.089263916,
- 283.884643555,
- 295.311279297,
- 289.575714111,
- 286.001953125,
- 288.381286621,
- 298.427124023,
- 292.479431152,
- 289.191467285,
- 290.576049805,
- 298.209472656,
- 293.322875977,
- 288.494506836,
- 288.694274902,
- 296.971862793,
- 291.222229004,
- 286.40802002,
- 287.488769531,
- 296.663146973,
- 289.671356201,
- 286.09979248,
- 288.075256348,
- 297.300292969,
- 290.362335205,
- 285.22467041,
- 287.296569824,
- 297.332366943,
- 291.09677124,
- 286.896789551
- ],
- "steps": [
- "6",
- "12",
- "18",
- "24",
- "30",
- "36",
- "42",
- "48",
- "54",
- "60",
- "66",
- "72",
- "78",
- "84",
- "90",
- "96",
- "102",
- "108",
- "114",
- "120",
- "126",
- "132",
- "138",
- "144",
- "150",
- "156",
- "162",
- "168",
- "174",
- "180",
- "186",
- "192",
- "198",
- "204",
- "210",
- "216",
- "222",
- "228",
- "234",
- "240"
- ],
- "ten": [
- 285.911987305,
- 294.739105225,
- 287.727111816,
- 282.934997559,
- 284.190856934,
- 296.498565674,
- 288.160766602,
- 281.816223145,
- 281.842407227,
- 289.553070068,
- 284.427032471,
- 279.781066895,
- 282.046020508,
- 293.385620117,
- 287.812683105,
- 284.664245605,
- 287.527770996,
- 297.655578613,
- 291.178283691,
- 287.245056152,
- 288.964691162,
- 295.305419922,
- 289.96105957,
- 283.075164795,
- 282.728881836,
- 290.234741211,
- 285.536987305,
- 280.936248779,
- 281.686645508,
- 289.268493652,
- 283.625823975,
- 278.466369629,
- 279.764862061,
- 288.233764648,
- 282.761962891,
- 277.706848145,
- 279.742858887,
- 289.525115967,
- 282.982940674,
- 278.549194336
- ],
- "twenty_five": [
- 286.245574951,
- 295.061462402,
- 288.001342773,
- 283.225585938,
- 284.544494629,
- 297.828979492,
- 288.666809082,
- 282.343322754,
- 282.142211914,
- 290.33203125,
- 284.803100586,
- 280.155303955,
- 282.609680176,
- 293.974304199,
- 288.482177734,
- 284.900726318,
- 287.725952148,
- 297.871826172,
- 291.526275635,
- 287.853515625,
- 289.384521484,
- 296.569763184,
- 291.147644043,
- 285.163146973,
- 284.894287109,
- 292.628631592,
- 287.680847168,
- 282.688781738,
- 283.298797607,
- 291.160827637,
- 285.762390137,
- 279.80847168,
- 280.99029541,
- 289.780883789,
- 284.830627441,
- 279.580291748,
- 281.31463623,
- 290.912841797,
- 284.874389648,
- 279.867248535
- ]
- },
- "api_version": "v1",
- "date": "20170103",
- "distance": {
- "angle": 203.63258681,
- "direction": "south-west",
- "distance": 5,
- "distance_unit": "km"
- },
- "ens_height": 907.186218262,
- "ens_location": {
- "latitude": 24.9511890411,
- "longitude": 42.9764442444
- },
- "expver": "0001",
- "hres_height": 889.378417969,
- "land_sea_mask": 1.0,
- "points_along_meridian": 1280,
- "time": "0000",
- "user_location": {
- "latitude": 25.0,
- "longitude": 43.0
- }
-}
\ No newline at end of file
diff --git a/notebook/Cross-section.ipynb b/notebook/Cross-section.ipynb
deleted file mode 100644
index c416ba8..0000000
--- a/notebook/Cross-section.ipynb
+++ /dev/null
@@ -1,63 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# How to display a Netcdf File : Cross section example.\n",
- "\n",
- "### First we load Magics"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import Magics.macro as magics"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "### We define the cartesian view "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/Untitled.ipynb b/notebook/Untitled.ipynb
deleted file mode 100644
index 983bf2b..0000000
--- a/notebook/Untitled.ipynb
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "ImportError",
- "evalue": "No module named 'Magics'",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-2-278566a0c059>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mMagics\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmacro\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mmagics\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mmagics\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0 [...]
- "\u001b[0;31mImportError\u001b[0m: No module named 'Magics'"
- ]
- }
- ],
- "source": [
- "import Magics.macro as magics\n",
- "\n",
- "magics.plot(magics.mcoast())\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.2"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/notebook/Untitled1.ipynb b/notebook/Untitled1.ipynb
deleted file mode 100644
index cbe7de7..0000000
--- a/notebook/Untitled1.ipynb
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import Magics.macro\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "magics.plot"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.2"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/notebook/WCS.ipynb b/notebook/WCS.ipynb
index c7cbcc9..6b51541 100644
--- a/notebook/WCS.ipynb
+++ b/notebook/WCS.ipynb
@@ -29,13 +29,23 @@
"outputs": [
{
"data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOydd5wWxf345w6OA1RAFPUEY6KCBjWaGE2+aV+NRn8aNSaW9C/G3mIUNXaNBWvEBigiikjv\n/ajHUe44rvBc7723p/c6vz8W9va2PVtm23Of98sXPjc7OzP72dnZ2ZlPScMYIwAAAAAAAIAc6UY3\nAAAAAAAAINWACRYAAAAAAABhYIIFAAAAAABAGJhgAQAAAAAAEAYmWAAAAAAAAISBCRYAAAAAAABh\nYIIFAAAAAABAGJhgAQAAAAAAEAYmWAAAAAAAAISBCRYAAAAAAABhYIIFAAAAAABAGJhgAQAAAAAA\nEAYmWAAAAAAAAISBCRYAAAAAAABhYIIFAAAAAABAGJhgAQAAAAAAEAYmWAAAAAAAAISBCRYAAAAA\nAABh [...]
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd3xb1fk/8HO1tyXvGSeOnUE2YWVAQwhQSkgLHZRSoFAa2nRCx7df+qOL0tIBdJC2hPYb\nWqA0bQOUhA0hIRASMpyYLM94b9mytce99/eHjCxrXklX697P+5U/5KOrc0+sxH50znmeQ7EsSwAA\nAACAP5JsDwAAAABAaBBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAA\nzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYA\nAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAMARYAAAAAzxBgAQAAAPAM\nARYA [...]
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"metadata": {},
"output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ "<function __main__.graph>"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
}
],
"source": [
@@ -59,12 +69,12 @@
" \n",
" \n",
" \n",
- " return magics.graph(xx, yy, \n",
+ " return magics.graph(yy, xx, \n",
" title = \"Time series %s at %d/%d\" % ( param , lat, lon), \n",
" graph = { \"graph_line_colour\" : color, \"graph_line_style\" : style },\n",
" )\n",
" \n",
- "\n",
+ "# , \n",
"\n",
"interact(graph, lon=widgets.IntSlider(min=-180,max=180,step=1,value=10,continuous_update=False),\n",
" lat=widgets.IntSlider(min=-90,max=90,step=1,value=10,continuous_update=False),\n",
diff --git a/notebook/WMS.ipynb b/notebook/WMS.ipynb
deleted file mode 100644
index 2a8c485..0000000
--- a/notebook/WMS.ipynb
+++ /dev/null
@@ -1,136 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import requests\n",
- "from IPython.display import Image\n",
- "import xmltodict\n",
- "import ipywidgets as widgets\n",
- "from ipywidgets import interact"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "\n",
- "url = 'http://apps.ecmwf.int/wms/' \n",
- "\n",
- "capa = {\n",
- " \"token\": \"public\",\n",
- " \"request\": \"GetCapabilities\",\n",
- " \"version\": \"1.1.1\",\n",
- " \n",
- " }\n",
- "\n",
- "\n",
- "\n",
- "\n",
- "capa = requests.get(url, capa, )\n",
- "\n",
- "layers = xmltodict.parse(capa.text)\n",
- "options = []\n",
- "for layer in layers[\"WMT_MS_Capabilities\"][\"Capability\"][\"Layer\"][\"Layer\"]:\n",
- " options.append(layer[\"Name\"])\n",
- " \n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "200\n"
- ]
- },
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAEsCAYAAAAfPc2WAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOydZ2BUxdfGz9yyfdN7D0lIIyEkoffeQelVkCYgSlUsgAqINEEsYKEqSBFUepHeQwsJISGF\nhPS+m2y7u7fN+4E/vCCggAGC3t8nErK7s7v3zjxzzjPnIIwxBgkJCQkJCQkJiRqDeNEDkJCQkJCQ\nkJD4tyEJLAkJCQkJCQmJGkYSWBISEhISEhISNYwksCQkJCQkJCQkahhJYElISEhISEhI1DCSwJKQ\nkJCQkJCQqGEkgSUhISEhISEhUcNIAktCQkJCQkJCooaRBJaEhISEhISERA1DvegBSEhI/DWCIMDp\n06fxr7/usOj1epDRtEiQhCjwPFKpFPz9f40AgLi7cUII3fNvAiECIQAAgiCQv78fGR4eqQgNDQV/\nf//n [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "def getMap(param):\n",
- " params = {\n",
- " \"token\": \"public\",\n",
- " \"request\": \"GetMap\",\n",
- " \"version\": \"1.1.1\",\n",
- " \"srs\": \"EPSG:4326\",\n",
- " \"layers\": \"background,%s,foreground\" % param,\n",
- " \"width\": 600,\n",
- " \"height\": 300,\n",
- " \"format\": \"image/png\",\n",
- " }\n",
- "\n",
- " r= requests.get(url,params, )\n",
- " print r.status_code\n",
- "\n",
- " with open('workfile.png', 'w') as png:\n",
- " png.write(r.content)\n",
- " return Image(filename=\"workfile.png\")\n",
- "\n",
- "interact(getMap, param = widgets.Dropdown( options= options) )"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/array-mars.ipynb b/notebook/array-mars.ipynb
deleted file mode 100644
index d5377e0..0000000
--- a/notebook/array-mars.ipynb
+++ /dev/null
@@ -1,345 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from ecmwfapi import ECMWFService"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2t.grib\n"
- ]
- }
- ],
- "source": [
- "target = \"2t.grib\"\n",
- "print target"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "I get the data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2017-01-05 15:24:51 ECMWF API python library 1.4.1\n",
- "2017-01-05 15:24:51 ECMWF API at https://api.ecmwf.int/v1\n",
- "2017-01-05 15:24:51 Welcome Sylvie Lamy-Thepaut\n",
- "2017-01-05 15:24:52 In case of problems, please check https://software.ecmwf.int/wiki/display/WEBAPI/Troubleshooting or contact calldesk at ecmwf.int\n",
- "2017-01-05 15:24:52 In case of delays, please check the MARS service activity page http://apps.ecmwf.int/mars-activity/\n",
- "2017-01-05 15:24:52 Request submitted\n",
- "2017-01-05 15:24:52 Request id: 586e573274a7fb520d5c6f04\n",
- "2017-01-05 15:24:52 Request is queued\n",
- "Calling '['nice', 'mars', '/tmp/tmp-_marsVkrWVA.req']'\n",
- "mars - WARN -\n",
- "mars - WARN - From 9 February 2016 10AM (UTC) MARS uses versions of\n",
- "mars - WARN - libemos newer than 4.3.0. For more details, see\n",
- "mars - WARN - https://software.ecmwf.int/wiki/display/EMOS/Bug+fix+implemented+in+EMOSLIB+4.3.x\n",
- "mars - WARN -\n",
- "PPDIR is /var/tmp/ppdir/x86_64\n",
- "mars - INFO - 20170105.142451 - Welcome to MARS with grib_api and ODB\n",
- "mars - INFO - 20170105.142451 - MARS Client build stamp: 20160429081542\n",
- "mars - INFO - 20170105.142451 - MARS Client version: 6.15.2\n",
- "mars - INFO - 20170105.142451 - EMOSLIB version: 441\n",
- "mars - INFO - 20170105.142451 - Using grib_api version 1.15.0\n",
- "mars - INFO - 20170105.142451 - Using odb_api version: 0.11.0 (file format version: 0.5)\n",
- "mars - INFO - 20170105.142451 - Maximum retrieval size is 20.00 G\n",
- "retrieve,class=od,dataset=od,date=-1,expect=any,grid=0.5/0.5,levtype=sfc,padding=0,param=167.128,step=6,time=0,type=fcmars - INFO - 20170105.142451 - Automatic split by date is on\n",
- "\n",
- "mars - INFO - 20170105.142451 - Processing request 1\n",
- "\n",
- "RETRIEVE,\n",
- " DATASET = od,\n",
- " CLASS = OD,\n",
- " TYPE = FC,\n",
- " STREAM = OPER,\n",
- " EXPVER = 0001,\n",
- " REPRES = GG,\n",
- " LEVTYPE = SFC,\n",
- " PARAM = 167.128,\n",
- " TIME = 0000,\n",
- " STEP = 6,\n",
- " DOMAIN = G,\n",
- " RESOL = AUTO,\n",
- " GRID = 0.5/0.5,\n",
- " PADDING = 0,\n",
- " EXPECT = ANY,\n",
- " DATE = 20170104\n",
- "\n",
- "mars - INFO - 20170105.142451 - Web API request id: 586e573274a7fb520d5c6f04\n",
- "mars - INFO - 20170105.142451 - Requesting any number of fields (request describes 1)\n",
- "mars - INFO - 20170105.142451 - Calling mars on 'marsod', callback on 60868\n",
- "mars - INFO - 20170105.142452 - Server task is 31 [marsod]\n",
- "mars - INFO - 20170105.142452 - Request cost: 1 field, 12.5929 Mbytes online, nodes: mvr01 [marsod]\n",
- "mars - INFO - 20170105.142452 - Transfering 13204588 bytes\n",
- "2017-01-05 15:24:54 Request is active\n",
- "mars - INFO - 20170105.142452 - 1 field retrieved from 'marsod'\n",
- "mars - INFO - 20170105.142452 - 1 field has been interpolated\n",
- "mars - INFO - 20170105.142452 - Request time: wall: 1 sec\n",
- "mars - INFO - 20170105.142452 - Read from network: 12.59 Mbyte(s) in < 1 sec [137.26 Mbyte/sec]\n",
- "mars - INFO - 20170105.142452 - Writing to target file: 507.76 Kbyte(s) in < 1 sec [887.05 Mbyte/sec]\n",
- "mars - INFO - 20170105.142452 - No errors reported\n",
- "Process '['nice', 'mars', '/tmp/tmp-_marsVkrWVA.req']' finished\n",
- "2017-01-05 15:24:59 Request is complete\n",
- "2017-01-05 15:24:59 Transfering 507.762 Kbytes into 2t.grib\n",
- "2017-01-05 15:24:59 From http://stream.ecmwf.int/data/atls01/data/data01/scratch/_mars-atls01-95e2cf679cd58ee9b4db4dd119a05a8d-ZE8npS.grib\n",
- "2017-01-05 15:25:00 Transfer rate 618.554 Kbytes/s\n",
- "2017-01-05 15:25:00 Done.\n"
- ]
- }
- ],
- "source": [
- "\n",
- "\n",
- "key = {\n",
- " \"url\" : \"https://api.ecmwf.int/v1\",\n",
- " \"key\" : \"83253855c912864513eb33f5fb1de322\",\n",
- " \"email\" : \"Sylvie.Lamy-Thepaut at ecmwf.int\"\n",
- " }\n",
- "\n",
- "request = {\n",
- " \"dataset\" : \"od\",\n",
- " \"class\" : \"od\",\n",
- " \"date\" : \"-1\",\n",
- " \"levtype\" : \"sfc\",\n",
- " \"param\" : \"167.128\",\n",
- " \"step\" : 6,\n",
- " \"type\" : \"fc\",\n",
- " \"time\" : 0,\n",
- " \"grid\" : [0.5,0.5]\n",
- " }\n",
- "\n",
- "mars = ECMWFService(\"mars\", **key) \n",
- "mars.execute(request, target)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### The data have been retrieved and saved in a grib file called 2t.grib\n",
- "We will use gribapi to read the grib in a numpy array, and to extract the necessary information to georeference the plot."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import Magics.macro as magics\n",
- "import gribapi as grib \n",
- "import numpy as numpy \n",
- "import json "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "720 361\n",
- "{'typeOfLevel': 'surface', 'marsStream': 'oper', 'level': 0, 'marsClass': 'od', 'marsType': 'fc', 'units': 'K', 'paramId': 167}\n"
- ]
- }
- ],
- "source": [
- "target = \"2t.grib\"\n",
- "file = open(target)\n",
- "\n",
- "#Getting the first message from the file\n",
- "field = grib.grib_new_from_file(file)\n",
- "\n",
- "nj = grib.grib_get(field,\"Nj\")\n",
- "ni = grib.grib_get(field,\"Ni\")\n",
- "\n",
- "print ni, nj\n",
- "metadata = { \"paramId\" : grib.grib_get(field,\"paramId\"),\n",
- " \"units\" : grib.grib_get(field,\"units\"),\n",
- " \"typeOfLevel\": grib.grib_get(field,\"typeOfLevel\"), \n",
- " \"marsType\": grib.grib_get(field,\"marsType\"), \n",
- " \"marsClass\": grib.grib_get(field,\"marsClass\"), \n",
- " \"marsStream\": grib.grib_get_string(field,\"marsStream\"),\n",
- " \"level\": grib.grib_get(field,\"level\") } \n",
- "\n",
- "print metadata"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Latitude 90.0 Step -0.5\n",
- "Longitude 0.0 Step 0.5\n"
- ]
- }
- ],
- "source": [
- "firstlat = grib.grib_get(field, \"latitudeOfFirstGridPointInDegrees\")\n",
- "steplat = -grib.grib_get(field, \"jDirectionIncrementInDegrees\")\n",
- "\n",
- "firstlon = grib.grib_get(field, \"longitudeOfFirstGridPointInDegrees\")\n",
- "steplon = grib.grib_get(field, \"iDirectionIncrementInDegrees\")\n",
- "\n",
- "print \"Latitude\", firstlat, \"Step\", steplat\n",
- "print \"Longitude\", firstlon, \"Step\", steplon"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "(361, 720)\n"
- ]
- },
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdeXwU9f0/8NfM7L3JZpOQBEIg4YZwKoeoqIgV73pWv61nsVVLrW212mo9qFVrtbban614\nV6Wt1FsRD1ABuS/DDQkQCLmPzbH3MTO/PzYsy+5mswuToPB6PvgjzH7m/Zn97Gdm3vuZz8wKqqqC\niIiIiLQjHusNICIiIjreMMEiIiIi0hgTLCIiIiKNMcEiIiIi0hgTLCIiIiKNMcEiIiIi0hgTLCIi\nIiKNMcEiIiIi0hgTLCIiIiKNMcEiIiIi0hgTLCIiIiKNMcEiIiIi0hgTLCIiIiKNMcEiIiIi0hgT\nLCIiIiKNMcEiIiIi0hgTLCIiIiKNMcEiIiIi0hgTLCIiIiKNMcEiIiIi0hgTLCIiIiKNMcEiIiIi\n0hgT [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "#Getting the field values\n",
- "values = grib.grib_get_values(field).reshape(nj, ni)\n",
- "\n",
- "data = magics.minput( input_field = values,\n",
- " input_field_initial_latitude = firstlat,\n",
- " input_field_latitude_step = steplat,\n",
- " input_field_initial_longitude = firstlon,\n",
- " input_field_longitude_step = steplon,\n",
- " input_mars_metadata = json.dumps(metadata),\n",
- " )\n",
- "\n",
- "#data = magics.mgrib(grib_input_file_name=target)\n",
- " \n",
- "#Setting the field contour \n",
- "contour = magics.mcont( \n",
- " contour_shade= \"on\",\n",
- " legend= \"on\",\n",
- " contour_highlight = \"off\",\n",
- " contour_shade_method = \"area_fill\",\n",
- " contour_shade_colour_direction = \"clockwise\",\n",
- " contour_shade_colour_method = \"calculate\",\n",
- " contour_shade_max_level_colour= \"red\",\n",
- " contour_shade_min_level_colour= \" blue\")\n",
- "\n",
- "#Setting the title\n",
- "title = magics.mtext(text_lines=[\"<magics_title/>\", \"Using Grib API and arrays...\"], \n",
- " text_colour=\"charcoal\",\n",
- " text_font_size='0.8',\n",
- " text_justification='left')\n",
- "\n",
- "europe = magics.mmap(\n",
- " subpage_map_projection = \"cylindrical\",\n",
- " subpage_lower_left_latitude = -90.00,\n",
- " subpage_lower_left_longitude = 0.00,\n",
- " subpage_upper_right_latitude = 90.00,\n",
- " subpage_upper_right_longitude = 360.00\n",
- ")\n",
- "contour = magics.mcont(\n",
- " contour_automatic_setting=\"ecchart\",\n",
- " legend=\"on\"\n",
- ")\n",
- "\n",
- "legend = magics.mlegend( legend_display_type = \"continuous\")\n",
- "#Plot the map\n",
- "magics.plot( europe, data, contour, magics.mcoast(), title)\n",
- "\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/boxplot.ipynb b/notebook/boxplot.ipynb
deleted file mode 100644
index 2b961a6..0000000
--- a/notebook/boxplot.ipynb
+++ /dev/null
@@ -1,224 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# How to create a BoxPlot "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### First we import magics"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import Magics.macro as magics"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Define the projection"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nO3deXxU9b3/8e9kJpN9BRJj2AkCBnBhU0SU4oILVpFer9WKrb1W7RUrdWn7a7W2pXovRYTa\nXuOG1lilooCgKHWXIAoCRggkYUsggYTsk2T2md8fB6dpWJJz/M7Mdw6v5x8+JpOzfc85+fDxzHnP\nsQSDQQEAAAB54qK9AQAAAGZDgwUAACAZDRYAAIBkNFgAAACS0WABAABIRoMFAAAgGQ0WAACAZDRY\nAAAAktFgAQAASEaDBQAAIBkNFgAAgGQ0WAAAAJLRYAEAAEhGgwUAACAZDRYAAIBkNFgAAACS0WAB\nAABIRoMFAAAgGQ0WAACAZDRYAAAAktFgAQAASEaDBQAAIBkNFgAAgGQ0WAAAAJLRYAEAAEhGgwUA\nACAZ [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "\n",
- "map = magics.mmap(subpage_map_projection = \"cartesian\",\n",
- " subpage_x_axis_type = 'date',\n",
- " subpage_y_axis_type = 'regular',\n",
- " subpage_x_date_min = '2016-11-03 00:00',\n",
- " subpage_x_date_max = '2016-11-13 12:00',\n",
- " subpage_y_min = 10.,\n",
- " subpage_y_max = 40.,\n",
- " subpage_y_position = 5.)\n",
- "\n",
- "horizontal_axis = magics.maxis(axis_orientation = \"horizontal\",\n",
- " axis_type = 'date',\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " axis_minor_tick ='on',\n",
- " axis_minor_grid ='on',\n",
- " axis_minor_grid_line_style = \"dot\",\n",
- " axis_minor_grid_colour = \"grey\",\n",
- " axis_title = 'on',\n",
- " axis_title_text = \"Time...\",\n",
- " )\n",
- "vertical_axis = magics.maxis(axis_orientation = \"vertical\",\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " )\n",
- "title = magics.mtext(text_lines=['Setting up a Box Plot'])\n",
- "magics.plot(map, horizontal_axis, vertical_axis, title)\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Defining the input data .. \n",
- "In this example we are using a 10 days temperature forecast"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import numpy\n",
- "steps= ['2016-11-03 06:00', '2016-11-03 12:00', '2016-11-03 18:00', \n",
- " '2016-11-04 00:00', '2016-11-04 06:00', '2016-11-04 12:00', '2016-11-04 18:00', \n",
- " '2016-11-05 00:00', '2016-11-05 06:00', '2016-11-05 12:00', '2016-11-05 18:00', \n",
- " '2016-11-06 00:00', '2016-11-06 06:00', '2016-11-06 12:00', '2016-11-06 18:00', \n",
- " '2016-11-07 00:00', '2016-11-07 06:00', '2016-11-07 12:00', '2016-11-07 18:00', \n",
- " '2016-11-08 00:00', '2016-11-08 06:00', '2016-11-08 12:00', '2016-11-08 18:00', \n",
- " '2016-11-09 00:00', '2016-11-09 06:00', '2016-11-09 12:00', '2016-11-09 18:00', \n",
- " '2016-11-10 00:00', '2016-11-10 06:00', '2016-11-10 12:00', '2016-11-10 18:00', \n",
- " '2016-11-11 00:00', '2016-11-11 06:00', '2016-11-11 12:00', '2016-11-11 18:00', \n",
- " '2016-11-12 00:00', '2016-11-12 06:00', '2016-11-12 12:00', '2016-11-12 18:00', \n",
- " '2016-11-13 00:00']\n",
- "\n",
- "min = numpy.array([ 20.11, 22.13, 26.13, 22.93, 20.19, 23.61, 28.19, 23.66,\n",
- " 21.63, 25.32, 29.07, 23.35, 22.26, 24.88, 28.81, 23.48,\n",
- " 20.83, 22.85, 26.6 , 21.36, 19.44, 22.81, 25.14, 20.95,\n",
- " 20.12, 22.74, 23.64, 20.62, 19.52, 22.31, 27.21, 21.16,\n",
- " 20.55, 23.7 , 25.92, 21.48, 20.99, 22.06, 23.51, 20.74])\n",
- "max = numpy.array([ 21.87, 25.78, 30.05, 24.85, 22.42, 27.4 , 32.44, 26.14,\n",
- " 23.29, 27.8 , 34.48, 27.21, 24.19, 28.01, 33.23, 27.4 ,\n",
- " 23.6 , 27.64, 34.16, 26.57, 22.8 , 27.02, 35.19, 26.19,\n",
- " 22.7 , 26.97, 32.82, 25.82, 22.55, 27.33, 33.13, 26.61,\n",
- " 23.21, 27.79, 34.48, 28.86, 25.17, 29.95, 34.86, 28.17])\n",
- "seventyfive = [ 21.05, 24.83, 28.67, 24.32, 21.99, 26.12, 30.73, 25.27,\n",
- " 22.83, 27.49, 32.76, 26.43, 23.32, 26.93, 32.07, 25.99,\n",
- " 22.63, 26.83, 32. , 25.56, 22.21, 25.99, 31.17, 24.97,\n",
- " 22. , 26.16, 30.79, 24.68, 21.44, 26.05, 31.51, 25.37,\n",
- " 22.23, 26.93, 32.31, 25.92, 22.9 , 27.67, 31.92, 25.75]\n",
- "twentyfive = [ 20.45, 23.53, 27.29, 23.54, 21.29, 24.86, 29.28, 24.42,\n",
- " 22.4 , 26.59, 31.12, 25.42, 22.7 , 26.09, 30.51, 25.11,\n",
- " 21.91, 25.93, 29.79, 24.16, 21.57, 25.04, 28.95, 23.51,\n",
- " 21.11, 25.05, 28.59, 22.86, 20.83, 24.96, 29.7 , 23.38,\n",
- " 21.27, 25.32, 29.15, 23.73, 21.73, 25.26, 27.33, 23.05]\n",
- "median = [ 20.87, 24.16, 27.86, 23.75, 21.78, 25.31, 30.02, 24.81,\n",
- " 22.58, 27.13, 31.76, 25.74, 23.08, 26.58, 31.54, 25.5 ,\n",
- " 22.3 , 26.35, 31.07, 24.95, 21.9 , 25.5 , 29.79, 24.35,\n",
- " 21.48, 25.66, 29.74, 23.95, 21.11, 25.58, 30.3 , 24.39,\n",
- " 21.73, 26.18, 31.14, 24.72, 22.43, 26.75, 29.92, 24.19]\n",
- "\n",
- "\n",
- "\n",
- "boxplot = magics.mboxplot(boxplot_date_positions=steps,\n",
- " boxplot_minimum_values = min,\n",
- " boxplot_maximum_values = max,\n",
- " boxplot_box_upper_values = seventyfive,\n",
- " boxplot_box_lower_values = twentyfive,\n",
- " boxplot_median_values = median,\n",
- " boxplot_box_width = 0.5,\n",
- " boxplot_box_colour = \"navy\")\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Then we redefine the projection to take into account the values "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdeXxU1f0//jtLZjKZyWRfJ2QhwbAIyiLKLlWsuNBqsVpLBYuforZi3Wr1W2ndqtaPpVBb\npEWskFoXFNxYxI2PYKksAiESICQQAiE7mSWzz/z+GH90MveSufc9d84seT0f/BGv98y5N3Nyc3Ln\nvO5b4ff7OQAAAACQjzLWBwAAAACQbDDBAgAAAJAZJlgAAAAAMsMECwAAAEBmmGABAAAAyAwTLAAA\nAACZYYIFAAAAIDNMsAAAAABkhgkWAAAAgMwwwQIAAACQGSZYAAAAADLDBAsAAABAZphgAQAAAMgM\nEywAAAAAmWGCBQAAACAzTLAAAAAAZIYJFgAAAIDMMMECAAAAkBkmWAAAAAAywwQLAAAAQGaYYAEA\nAADI [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "map = magics.mmap(subpage_map_projection = \"cartesian\",\n",
- " subpage_x_axis_type = 'date',\n",
- " subpage_y_axis_type = 'regular',\n",
- " subpage_x_date_min = steps[0],\n",
- " subpage_x_date_max = steps[-1],\n",
- " subpage_y_min = min.min(),\n",
- " subpage_y_max = max.max(),\n",
- " subpage_y_position = 5.)\n",
- "magics.plot(map, horizontal_axis, vertical_axis, boxplot, title)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/cartesian_projection.ipynb b/notebook/cartesian_projection.ipynb
deleted file mode 100644
index e009fae..0000000
--- a/notebook/cartesian_projection.ipynb
+++ /dev/null
@@ -1,354 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# How to plot a set up a cartesian projection with Magics"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### First import Magics\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import Magics.macro as magics"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "###### First we have to define a cartesian projection.\n",
- "This can be done use the magics.mmap object. <br/>\n",
- "The documentation can be found in the <a href='https://software.ecmwf.int/wiki/display/MAGP/Subpage+-+Projection'> Manual</a>"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nO3de5yWdZ3w8d8cYJiBATnNCCNyGhREwsRTkSULpKnZrmltVLNulpKWu5araz37sjTa7Slz\nrawdn5JK10TAEyR4zFQMS8U8IAoOCIIcRhhnYM6H54/b7maHg+3L7wyk7/fLP+7DdV+/6/rd9+vm\n43VfXOR0dHQkAADi5O7vDQAAeKcRWAAAwQQWAEAwgQUAEExgAQAEE1gAAMEEFgBAMIEFABBMYAEA\nBBNYAADBBBYAQDCBBQAQTGABAAQTWAAAwQQWAEAwgQUAEExgAQAEE1gAAMEEFgBAMIEFABBMYAEA\nBBNYAADBBBYAQDCBBQAQTGABAAQTWAAAwQQWAEAwgQUAEExgAQAEE1gAAMEEFgBAMIEFABBMYAEA\nBBNY [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "map = magics.mmap(subpage_map_projection = \"cartesian\",\n",
- " subpage_x_axis_type = 'regular',\n",
- " subpage_y_axis_type = 'regular',\n",
- " subpage_x_min = -100.,\n",
- " subpage_x_max = +200.,\n",
- " subpage_y_min = -20.,\n",
- " subpage_y_max = 20. )\n",
- "horizontal_axis = magics.maxis(axis_orientation = \"horizontal\",)\n",
- "vertical_axis = magics.maxis(axis_orientation = \"vertical\",)\n",
- "title = magics.mtext(text_lines=['Cartesian projection'])\n",
- "magics.plot(map, horizontal_axis, vertical_axis, title)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "###### Now we can explore the attributes of the axis : colour, grid, minor ticks etc .. \n",
- "https://software.ecmwf.int/wiki/display/MAGP/Axis"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nO3deXxV9Z3/8e/NvocQSAghQkhAdhTcWkVhADcsthRrtRodddSK0qm1OjpTrVpsO1VxKe0v\njooVqiCLIghYF3CBgiL7EiBsgUAgK9n3+/vjMKeZJETL+8sFjq/no38kNzfnnPvCB3x6cz+5Pr/f\nbwAAAGBP0Km+AAAAAK9hwAIAALCMAQsAAMAyBiwAAADLGLAAAAAsY8ACAACwjAELAADAMgYsAAAA\nyxiwAAAALGPAAgAAsIwBCwAAwDIGLAAAAMsYsAAAACxjwAIAALCMAQsAAMAyBiwAAADLGLAAAAAs\nY8ACAACwjAELAADAMgYsAAAAyxiwAAAALGPAAgAAsIwBCwAAwDIGLAAAAMsYsAAAACxjwAIAALCM\nAQsA [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "horizontal_axis = magics.maxis(axis_orientation = \"horizontal\",\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " axis_minor_tick ='on',\n",
- " axis_minor_grid ='on',\n",
- " axis_minor_grid_line_style = \"dot\",\n",
- " axis_minor_grid_colour = \"grey\",\n",
- " )\n",
- "vertical_axis = magics.maxis(axis_orientation = \"vertical\",\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",)\n",
- "title = magics.mtext(text_lines=['Cartesian projection', 'Discovering the axis attributes'])\n",
- "magics.plot(map, horizontal_axis, vertical_axis, title)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### You can add a title to this axis "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nO3deXxU9b34/89kErITkkBCCAghYd+EgBtS4ALuF1qKVWmNuNSiIF736v1V64LVVqVqrY1f\nhRawgoKCbHHDFQqC7EsgGwSTELKSdbLMzO+Pwz2OSYi0nrwPzOf1fPSPLJM5Z17wwHfnzDvj8Hq9\nCgAAANYJsPsEAAAA/A0DFgAAgMUYsAAAACzGgAUAAGAxBiwAAACLMWABAABYjAELAADAYgxYAAAA\nFmPAAgAAsBgDFgAAgMUYsAAAACzGgAUAAGAxBiwAAACLMWABAABYjAELAADAYgxYAAAAFmPAAgAA\nsBgDFgAAgMUYsAAAACzGgAUAAGAxBiwAAACLMWABAABYjAELAADAYgxYAAAAFmPAAgAAsBgDFgAA\ngMUY [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "horizontal_axis = magics.maxis(axis_orientation = \"horizontal\",\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " axis_minor_tick ='on',\n",
- " axis_minor_grid ='on',\n",
- " axis_minor_grid_line_style = \"dot\",\n",
- " axis_minor_grid_colour = \"grey\",\n",
- " axis_title = 'on',\n",
- " axis_title_text = \"Example of <font colour='evergreen'> coloured title </font>\"\n",
- " )\n",
- "vertical_axis = magics.maxis(axis_orientation = \"vertical\",\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " axis_tip_title = 'on',\n",
- " axis_tip_title_text = \"Units\",\n",
- " axis_tip_title_colour = \"rgb(0.16,0.38,0.51)\")\n",
- "magics.plot(map, horizontal_axis, vertical_axis, title)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### You can define a specific list of ticks :\n",
- "axis_type = 'position_list'\n",
- "axis_tick_position_list --> the list of ticks you want in the system coordinates."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### You can also use you own labels "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nO3deZxVZeH48WcWGLZhd8YBUZYBRcUNTCs1CUjN0l6maaaoaWUu+FVLss20H5VpuWeYMaZo\noogiCEhquIAoKKiAIMMu+wDDDMzCbL8/Lt2GAXHpmRnA9/vlH/eee855nnvmvmY+nnvvIaWmpiYA\nABBPamNPAABgXyOwAAAiE1gAAJEJLACAyAQWAEBkAgsAIDKBBQAQmcACAIhMYAEARCawAAAiE1gA\nAJEJLACAyAQWAEBkAgsAIDKBBQAQmcACAIhMYAEARCawAAAiE1gAAJEJLACAyAQWAEBkAgsAIDKB\nBQAQmcACAIhMYAEARCawAAAiE1gAAJEJLACAyAQWAEBkAgsAIDKBBQAQmcACAIhMYAEARCawAAAi\nE1gA [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "horizontal_axis = magics.maxis(axis_orientation = \"horizontal\",\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " axis_minor_tick ='on',\n",
- " axis_minor_grid ='on',\n",
- " axis_minor_grid_line_style = \"dot\",\n",
- " axis_minor_grid_colour = \"grey\",\n",
- " axis_title = 'on',\n",
- " axis_title_text = \"Playing with a specific tick list...\",\n",
- " axis_type = 'position_list',\n",
- " axis_tick_position_list = [-100., -75., 0, 100, 150., 200.],\n",
- " axis_tick_label_type = \"label_list\",\n",
- " axis_tick_label_list = [\"label 1\", \n",
- " \"label 2\", \n",
- " \"<font colour='red'> origin </font>\", \n",
- " \"label 3\", \n",
- " \"label 4\", \n",
- " \"Final label\",],\n",
- " )\n",
- " \n",
- "vertical_axis = magics.maxis(axis_orientation = \"vertical\",\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " axis_tip_title = 'on',\n",
- " axis_tip_title_text = \"Units\",\n",
- " axis_tip_title_colour = \"rgb(0.16,0.38,0.51)\")\n",
- "magics.plot(map, horizontal_axis, vertical_axis, title)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Now let's work with some dates ..\n",
- "subpage_x_axis_type = <b> date </b>\n",
- "\n",
- "The format expected for <i>subpage_x_date_min</i> and <i>subpage_x_date_max</i> is YYYY-MM-DD HH:MM"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import datetime\n",
- "now = datetime.datetime.today()\n",
- "start_date = now.strftime(\"%Y-%m-%d 00:00\")\n",
- "later = now + datetime.timedelta(days=10)\n",
- "end_date = later.strftime(\"%Y-%m-%d 00:00\")\n",
- "map = magics.mmap(subpage_map_projection = \"cartesian\",\n",
- " subpage_x_axis_type = 'date',\n",
- " subpage_y_axis_type = 'logarithmic',\n",
- " subpage_x_date_min = start_date,\n",
- " subpage_x_date_max = end_date,\n",
- " subpage_y_min = 1000.,\n",
- " subpage_y_max = 20. )\n"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### But we have to redefine the horizontal axis too .. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nO3deXhV5bn38SfzRIAkkBBCZAoIAoIClqM4UKFa51K01WqqR09LcTravlpb36O1xx57bLWo\ntO6e1tRqBaqICELliEUZigUBERAkhEnClImEJDvJ3sn7x/LdTZksd55y8zx+P1cvr51k//ZaP/CK\nd/dadxLX1tZmAAAAYE+89gkAAAD4hgELAADAMgYsAAAAyxiwAAAALGPAAgAAsIwBCwAAwDIGLAAA\nAMsYsAAAACxjwAIAALCMAQsAAMAyBiwAAADLGLAAAAAsY8ACAACwjAELAADAMgYsAAAAyxiwAAAA\nLGPAAgAAsIwBCwAAwDIGLAAAAMsYsAAAACxjwAIAALCMAQsAAMAyBiwAAADLGLAAAAAsY8ACAACw\njAEL [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "horizontal_axis = magics.maxis(axis_orientation = \"horizontal\",\n",
- " axis_type = 'date',\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " axis_minor_tick ='on',\n",
- " axis_minor_grid ='on',\n",
- " axis_minor_grid_line_style = \"dot\",\n",
- " axis_minor_grid_colour = \"grey\",\n",
- " axis_title = 'on',\n",
- " axis_title_text = \"Playing with time axis...\",\n",
- " )\n",
- "vertical_axis = magics.maxis(axis_orientation = \"vertical\",\n",
- " axis_type = \"logarithmic\",\n",
- " axis_grid = \"on\",\n",
- " axis_grid_line_style = \"solid\",\n",
- " axis_grid_thickness = 1,\n",
- " axis_grid_colour = \"grey\",\n",
- " \n",
- " )\n",
- "magics.plot(map, horizontal_axis, vertical_axis, title)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/curve-python3.ipynb b/notebook/curve-python3.ipynb
deleted file mode 100644
index df760c0..0000000
--- a/notebook/curve-python3.ipynb
+++ /dev/null
@@ -1,163 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import Magics.macro as magics\n",
- "import numpy\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdZ1gU1/828NkCy9J7lyZFBQRRigVLjBV7TUzyM0ZN1BiNxhZRLFGxi8ZYYjf2ktgLYK8Y\nQRQEBaT3uoXt7Xlxnv9eXKAEdSjq/Xnhhcsu3xmYnb3nzCkMjUZDAQAAAAB9mM29AQAAAAAfGwQs\nAAAAAJohYAEAAADQDAELAAAAgGYIWAAAAAA0Q8ACAAAAoBkCFgAAAADNELAAAAAAaIaABQAAAEAz\nBCwAAAAAmiFgAQAAANAMAQsAAACAZghYAAAAADRDwAIAAACgGQIWAAAAAM0QsAAAAABohoAFAAAA\nQDMELAAAAACaIWABAAAA0AwBCwAAAIBmCFgAAAAANEPAAgAAAKAZAhYAAAAAzRCwAAAAAGiGgAUA\nAABA [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "magics.plot(magics.mcoast())"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nO3de5xVdb3w8d9cYJgZBhguMyIgAoOCSJh4zSwJzEumHdN6suR4spQ07VQePdbpVBp1eqpj\n6TGf4ah00kwF8oIJXkozMUwU84IoMMpVLgOMMzBXZub5Y9tuGi52Xn5nIH2//1p777XXb+3f3q/N\nh7UXi5z29vYEAECc3L29AwAA7zQCCwAgmMACAAgmsAAAggksAIBgAgsAIJjAAgAIJrAAAIIJLACA\nYAILACCYwAIACCawAACCCSwAgGACCwAgmMACAAgmsAAAggksAIBgAgsAIJjAAgAIJrAAAIIJLACA\nYAILACCYwAIACCawAACCCSwAgGACCwAgmMACAAgmsAAAggksAIBgAgsAIJjAAgAIJrAAAIIJLACA\nYAIL [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "map = magics.mmap(subpage_map_projection = \"cartesian\",\n",
- " subpage_x_axis_type = 'regular',\n",
- " subpage_y_axis_type = 'regular',\n",
- " subpage_x_min = -100.,\n",
- " subpage_x_max = +200.,\n",
- " subpage_y_min = -20.,\n",
- " subpage_y_max = 20. )\n",
- "horizontal_axis = magics.maxis(axis_orientation = \"horizontal\",)\n",
- "vertical_axis = magics.maxis(axis_orientation = \"vertical\",)\n",
- "title = magics.mtext(text_lines=['Cartesian projection'])\n",
- "magics.plot(map, horizontal_axis, vertical_axis, title)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOydaZAd13XfD2bfgdl3zAAkQYAABwD3TZQlWZLl2Eo5zuLIdlklf0lVKkoiqcykUtkqUdku\nJ6UqpfLBUsSkUowTJ1RKlmORlG2SWmguMkns26yYfcPs+5oPDT68efNe913O7Xtvz//3CZjp133f\nvNe3//fcc/7n0O7uLgEAAAAAAD7ybA8AAAAAACBpQGABAAAAADADgQUAAAAAwAwEFgAAAAAAMxBY\nAAAAAADMQGABAAAAADADgQUAAAAAwAwEFgAAAAAAMxBYAAAAAADMQGABAAAAADADgQUAAAAAwAwE\nFgAAAAAAMxBYAAAAAADMQGABAAAAADADgQUAAAAAwAwEFgAAAAAAMxBYAAAAAADMQGABAAAAADAD\ngQUA [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "\n",
- "map = magics.mmap(subpage_map_projection = \"cartesian\",\n",
- " subpage_x_axis_type = 'date',\n",
- " subpage_y_axis_type = 'regular',\n",
- " subpage_x_automatic = \"on\",\n",
- " subpage_y_automatic = \"on\",\n",
- " )\n",
- "horizontal_axis = magics.maxis(axis_orientation = \"horizontal\", axis_type='date')\n",
- "steps= ['2016-11-03 06:00', '2016-11-03 12:00', '2016-11-03 18:00', \n",
- " '2016-11-04 00:00', '2016-11-04 06:00', '2016-11-04 12:00', '2016-11-04 18:00', \n",
- " '2016-11-05 00:00', '2016-11-05 06:00', '2016-11-05 12:00', '2016-11-05 18:00', \n",
- " '2016-11-06 00:00', '2016-11-06 06:00', '2016-11-06 12:00', '2016-11-06 18:00', \n",
- " '2016-11-07 00:00', '2016-11-07 06:00', '2016-11-07 12:00', '2016-11-07 18:00', \n",
- " '2016-11-08 00:00', '2016-11-08 06:00', '2016-11-08 12:00', '2016-11-08 18:00', \n",
- " '2016-11-09 00:00', '2016-11-09 06:00', '2016-11-09 12:00', '2016-11-09 18:00', \n",
- " '2016-11-10 00:00', '2016-11-10 06:00', '2016-11-10 12:00', '2016-11-10 18:00', \n",
- " '2016-11-11 00:00', '2016-11-11 06:00', '2016-11-11 12:00', '2016-11-11 18:00', \n",
- " '2016-11-12 00:00', '2016-11-12 06:00', '2016-11-12 12:00', '2016-11-12 18:00', \n",
- " '2016-11-13 00:00']\n",
- "\n",
- "x = numpy.array([ 20.11, 22.13, 26.13, 22.93, 20.19, 23.61, 28.19, 23.66,\n",
- " 21.63, 25.32, 29.07, 23.35, 22.26, 24.88, 28.81, 23.48,\n",
- " 20.83, 22.85, 26.6 , 21.36, 19.44, 22.81, 25.14, 20.95,\n",
- " 20.12, 22.74, 23.64, 20.62, 19.52, 22.31, 27.21, 21.16,\n",
- " 20.55, 23.7 , 25.92, 21.48, 20.99, 22.06, 23.51, 20.74])\n",
- "\n",
- "y = numpy.array([ 21.87, 25.78, 30.05, 24.85, 22.42, 27.4 , 32.44, 26.14,\n",
- " 23.29, 27.8 , 34.48, 27.21, 24.19, 28.01, 33.23, 27.4 ,\n",
- " 23.6 , 27.64, 34.16, 26.57, 22.8 , 27.02, 35.19, 26.19,\n",
- " 22.7 , 26.97, 32.82, 25.82, 22.55, 27.33, 33.13, 26.61,\n",
- " 23.21, 27.79, 34.48, 28.86, 25.17, 29.95, 34.86, 28.17])\n",
- "\n",
- "min = magics.minput(input_x_type = \"date\", input_date_x_values = steps, input_y_values = x)\n",
- "max = magics.minput(input_x_type = \"date\", input_date_x_values = steps, input_y_values = y)\n",
- "\n",
- "blue = magics.mgraph()\n",
- "red = magics.mgraph(graph_line_colour = 'red')\n",
- "\n",
- "magics.plot(map, horizontal_axis, vertical_axis, min, blue, max, red) "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.5.2"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/notebook/epsgrams.ipynb b/notebook/epsgrams.ipynb
index f521e1a..83ac80b 100644
--- a/notebook/epsgrams.ipynb
+++ b/notebook/epsgrams.ipynb
@@ -19,7 +19,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 5,
"metadata": {
"collapsed": false
},
@@ -59,7 +59,7 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 6,
"metadata": {
"collapsed": false
},
@@ -68,11 +68,11 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "20170102\n",
+ "20161031\n",
"10days 2t\n",
- "20170103\n",
- "2017-01-03 17:12:44 ECMWF API python library 1.4.1\n",
- "2017-01-03 17:12:44 ECMWF API at https://api.ecmwf.int/v1\n",
+ "20161101\n",
+ "2016-11-01 15:16:31 ECMWF API python library 1.4.1\n",
+ "2016-11-01 15:16:31 ECMWF API at https://api.ecmwf.int/v1\n",
"GET https://api.ecmwf.int/v1/who-am-i\n",
"Code 200\n",
"Content-Type application/json\n",
@@ -87,7 +87,7 @@
" \"email\": \"Sylvie.Lamy-Thepaut at ecmwf.int\"\n",
"}\n",
"Status None\n",
- "2017-01-03 17:12:44 Welcome Sylvie Lamy-Thepaut\n",
+ "2016-11-01 15:16:31 Welcome Sylvie Lamy-Thepaut\n",
"GET https://api.ecmwf.int/v1/services/meteogram/news\n",
"Code 200\n",
"Content-Type application/json\n",
@@ -98,38 +98,34 @@
" \"code\": 200\n",
"}\n",
"Status None\n",
- "2017-01-03 17:12:44 Welcome to ECMWF Web API Meteogram Service\n",
- "2017-01-03 17:12:44 \n",
+ "2016-11-01 15:16:31 Welcome to ECMWF Web API Meteogram Service\n",
+ "2016-11-01 15:16:31 \n",
"POST https://api.ecmwf.int/v1/services/meteogram/requests\n",
"Code 303\n",
"Content-Type application/json\n",
"Content-Length None\n",
- "Location http://stream.ecmwf.int/data/atls18/data/data01/scratch/meteogram_data-atls18-95e2cf679cd58ee9b4db4dd119a05a8d-rSW0Jd.json\n",
+ "Location http://stream.ecmwf.int/data/atls01/data/data01/scratch/meteogram_data-atls01-95e2cf679cd58ee9b4db4dd119a05a8d-sY8zgm.json\n",
"{\n",
" \"status\": \"complete\", \n",
" \"code\": 303, \n",
- " \"name\": \"d1ab79cc-03f2-4bf8-9d4d-71be033cb40e\", \n",
- " \"href\": \"http://stream.ecmwf.int/data/atls18/data/data01/scratch/meteogram_data-atls18-95e2cf679cd58ee9b4db4dd119a05a8d-rSW0Jd.json\", \n",
+ " \"name\": \"e66af64d-b2d0-415c-a28b-18da5ecd466c\", \n",
+ " \"href\": \"http://stream.ecmwf.int/data/atls01/data/data01/scratch/meteogram_data-atls01-95e2cf679cd58ee9b4db4dd119a05a8d-sY8zgm.json\", \n",
" \"type\": \"application/json\", \n",
- " \"size\": 11708\n",
+ " \"size\": 11504\n",
"}\n",
"Status complete\n",
- "2017-01-03 17:12:45 Request submitted\n",
- "2017-01-03 17:12:45 Request id: d1ab79cc-03f2-4bf8-9d4d-71be033cb40e\n",
- "2017-01-03 17:12:45 Request is complete\n",
- "2017-01-03 17:12:45 Transfering 11.4336 Kbytes into 2t.json\n",
- "2017-01-03 17:12:45 From http://stream.ecmwf.int/data/atls18/data/data01/scratch/meteogram_data-atls18-95e2cf679cd58ee9b4db4dd119a05a8d-rSW0Jd.json\n",
- "2017-01-03 17:12:45 Transfer rate 870.139 Kbytes/s\n",
- "2017-01-03 17:12:45 Done.\n",
- "{'subpage_x_automatic': 'on', 'subpage_map_projection': 'cartesian', 'subpage_y_axis_type': 'regular', 'subpage_y_automatic': 'on', 'subpage_x_axis_type': 'date'}\n",
- "{'axis_orientation': 'horizontal', 'axis_months_label': 'off', 'axis_days_label_height': 0.35, 'axis_years_label': 'off', 'axis_line_colour': 'navy', 'axis_days_label_colour': 'navy', 'axis_type': 'date', 'axis_minor_tick': 'off', 'axis_tick_colour': 'navy', 'axis_grid': 'on', 'axis_grid_line_style': 'dash', 'axis_date_type': 'days', 'axis_minor_tick_colour=': 'navy', 'axis_grid_colour': 'navy', 'axis_days_label': 'both'}\n",
- "{'axis_orientation': 'vertical', 'axis_line_colour': 'navy', 'axis_tick_label_height': 0.35, 'axis_grid_reference_thickness': 1, 'axis_tick_label_colour': 'navy', 'axis_grid_reference_level': 0.0, 'axis_tick_colour': 'navy', 'axis_grid': 'on', 'axis_line': 'on', 'axis_grid_line_style': 'dash', 'axis_grid_colour': 'navy'}\n",
- "{'eps_box_width': 1.5, 'eps_graph_colour': u'green', 'eps_grey_legend': 'off', 'eps_legend_font_size': 0.35, 'eps_font_colour': 'navy', 'eps_deterministic_colour': 'black', 'eps_box_colour': 'green', 'eps_graph_box_colour': u'red', 'legend': 'off', 'eps_box_border_thickness': 2}\n"
+ "2016-11-01 15:16:33 Request submitted\n",
+ "2016-11-01 15:16:33 Request id: e66af64d-b2d0-415c-a28b-18da5ecd466c\n",
+ "2016-11-01 15:16:33 Request is complete\n",
+ "2016-11-01 15:16:33 Transfering 11.2344 Kbytes into 2t.json\n",
+ "2016-11-01 15:16:33 From http://stream.ecmwf.int/data/atls01/data/data01/scratch/meteogram_data-atls01-95e2cf679cd58ee9b4db4dd119a05a8d-sY8zgm.json\n",
+ "2016-11-01 15:16:33 Transfer rate 904.978 Kbytes/s\n",
+ "2016-11-01 15:16:33 Done.\n"
]
},
{
"data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd1xTZ/cA8JMFARkCylRBWbIUFYU6caHirgpVqNaqaNVXbPsrjtZRtcU9a93iQl/FvSeI\ng6WoiMqessIIG0JIcn9/XN80ZQTUXDI830/+SJ47nvPkxuvhjnNpBEEAQgghhBCSHbq8A0AIIYQQ\nUjWYYCGEEEIIyRgmWAghhBBCMoYJFkIIIYSQjGGChRBCCCEkY5hgIYQQQgjJGCZYCCGEEEIyhgkW\nQgghhJCMYYKFEEIIISRjmGAhhBBCCMkYJlgIIYQQQjKGCRZCCCGEkIxhgoUQQgghJGOYYCGEEEII\nyRgmWAghhBBCMoYJFkIIIYSQjGGChRBCCCEkY5hgIYQQQgjJGCZYCCGEEEIyhgkWQgghhJCMYYKF\nEEII [...]
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd1gUV9cA8LPL0puAiqAICAoCVqqKaERR7EQBC8FObC8aY+wtaoK9V4wiFoxiATsRbFRR\nVCz03ntbFpZt8/0xfhtemoCLu8x7fs8+T9g7d+69M0OW4527Z2gEQQBCCCGEEBIdurgHgBBCCCFE\nNRhgIYQQQgiJGAZYCCGEEEIihgEWQgghhJCIYYCFEEIIISRiGGAhhBBCCIkYBlgIIYQQQiKGARZC\nCCGEkIhhgIUQQgghJGIYYCGEEEIIiRgGWAghhBBCIoYBFkIIIYSQiGGAhRBCCCEkYhhgIYQQQgiJ\nGAZYCCGEEEIihgEWQgghhJCIYYCFEEIIISRiGGAhhBBCCIkYBlgIIYQQQiKGARZCCCGEkIhhgIUQ\nQggh [...]
"text/plain": [
"<IPython.core.display.Image object>"
]
@@ -141,8 +137,7 @@
"source": [
"\n",
"\n",
- "colour = widgets.Dropdown(\n",
- " options=['evergreen', \"navy\", 'ecmwf_blue', \"green\", 'blue'],\n",
+ "colour = widgets.ColorPicker(\n",
" concise= False,\n",
" description='Pick a color',\n",
" value='blue'\n",
@@ -169,7 +164,7 @@
" return magics.epsgram(parameter, \n",
" \"%s.json\" % parameter, \n",
" title = \"My title for %s\" % (parameter), \n",
- " epsgraph = { \"eps_box_colour\" : colour} )\n",
+ " colour = colour)\n",
"\n",
"from IPython.display import display\n",
"\n",
@@ -286,10 +281,17 @@
},
"widgets": {
"state": {
- "7af87027d8e44c07a98bac943a6fac9e": {
+ "b4420652ae1447a1bed6f953098f9e77": {
"views": [
{
- "cell_index": 2
+ "cell_index": 4
+ }
+ ]
+ },
+ "c1d9e98c8af74b34b18d52c87bd266c5": {
+ "views": [
+ {
+ "cell_index": 4
}
]
}
diff --git a/notebook/grib-mars.ipynb b/notebook/grib-mars.ipynb
deleted file mode 100644
index a2f18fe..0000000
--- a/notebook/grib-mars.ipynb
+++ /dev/null
@@ -1,218 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from ecmwfapi import ECMWFService"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2t.grib\n"
- ]
- }
- ],
- "source": [
- "target = \"2t.grib\"\n",
- "print target"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "I get the data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2017-01-05 10:28:28 ECMWF API python library 1.4.1\n",
- "2017-01-05 10:28:28 ECMWF API at https://api.ecmwf.int/v1\n",
- "2017-01-05 10:28:28 Welcome Sylvie Lamy-Thepaut\n",
- "2017-01-05 10:28:28 In case of problems, please check https://software.ecmwf.int/wiki/display/WEBAPI/Troubleshooting or contact calldesk at ecmwf.int\n",
- "2017-01-05 10:28:28 In case of delays, please check the MARS service activity page http://apps.ecmwf.int/mars-activity/\n",
- "2017-01-05 10:28:29 Request submitted\n",
- "2017-01-05 10:28:29 Request id: 586e11bc6168505487e50d8d\n",
- "2017-01-05 10:28:29 Request is queued\n",
- "Calling '['nice', 'mars', '/tmp/tmp-_marsKS2AW2.req']'\n",
- "mars - WARN -\n",
- "mars - WARN - From 9 February 2016 10AM (UTC) MARS uses versions of\n",
- "mars - WARN - libemos newer than 4.3.0. For more details, see\n",
- "mars - WARN - https://software.ecmwf.int/wiki/display/EMOS/Bug+fix+implemented+in+EMOSLIB+4.3.x\n",
- "mars - WARN -\n",
- "PPDIR is /var/tmp/ppdir/x86_64\n",
- "mars - INFO - 20170105.092829 - Welcome to MARS with grib_api and ODB\n",
- "mars - INFO - 20170105.092829 - MARS Client build stamp: 20160429081542\n",
- "mars - INFO - 20170105.092829 - MARS Client version: 6.15.2\n",
- "mars - INFO - 20170105.092829 - EMOSLIB version: 441\n",
- "mars - INFO - 20170105.092829 - Using grib_api version 1.15.0\n",
- "mars - INFO - 20170105.092829 - Using odb_api version: 0.11.0 (file format version: 0.5)\n",
- "mars - INFO - 20170105.092829 - Maximum retrieval size is 20.00 G\n",
- "retrieve,class=od,dataset=od,date=-1,expect=any,grid=0.5/0.5,levtype=sfc,padding=0,param=167.128,step=6,time=0,type=fcmars - INFO - 20170105.092829 - Automatic split by date is on\n",
- "\n",
- "mars - INFO - 20170105.092829 - Processing request 1\n",
- "\n",
- "RETRIEVE,\n",
- " DATASET = od,\n",
- " CLASS = OD,\n",
- " TYPE = FC,\n",
- " STREAM = OPER,\n",
- " EXPVER = 0001,\n",
- " REPRES = GG,\n",
- " LEVTYPE = SFC,\n",
- " PARAM = 167.128,\n",
- " TIME = 0000,\n",
- " STEP = 6,\n",
- " DOMAIN = G,\n",
- " RESOL = AUTO,\n",
- " GRID = 0.5/0.5,\n",
- " PADDING = 0,\n",
- " EXPECT = ANY,\n",
- " DATE = 20170104\n",
- "\n",
- "mars - INFO - 20170105.092829 - Web API request id: 586e11bc6168505487e50d8d\n",
- "mars - INFO - 20170105.092829 - Requesting any number of fields (request describes 1)\n",
- "mars - INFO - 20170105.092829 - Calling mars on 'marsod', callback on 36892\n",
- "2017-01-05 10:28:30 Request is active\n",
- "mars - INFO - 20170105.092830 - Server task is 962 [marsod]\n",
- "mars - INFO - 20170105.092830 - Request cost: 1 field, 12.5929 Mbytes online, nodes: mvr01 [marsod]\n",
- "mars - INFO - 20170105.092831 - Transfering 13204588 bytes\n",
- "mars - INFO - 20170105.092831 - 1 field retrieved from 'marsod'\n",
- "mars - INFO - 20170105.092831 - 1 field has been interpolated\n",
- "mars - INFO - 20170105.092831 - Request time: wall: 2 sec\n",
- "mars - INFO - 20170105.092831 - Read from network: 12.59 Mbyte(s) in < 1 sec [88.13 Mbyte/sec]\n",
- "mars - INFO - 20170105.092831 - Processing in marsod: wall: 2 sec\n",
- "mars - INFO - 20170105.092831 - Visiting marsod: wall: 2 sec\n",
- "mars - INFO - 20170105.092831 - Writing to target file: 507.76 Kbyte(s) in < 1 sec [856.41 Mbyte/sec]\n",
- "mars - INFO - 20170105.092831 - No errors reported\n",
- "Process '['nice', 'mars', '/tmp/tmp-_marsKS2AW2.req']' finished\n",
- "2017-01-05 10:28:35 Request is complete\n",
- "2017-01-05 10:28:35 Transfering 507.762 Kbytes into 2t.grib\n",
- "2017-01-05 10:28:35 From http://stream.ecmwf.int/data/atls19/data/data01/scratch/_mars-atls19-95e2cf679cd58ee9b4db4dd119a05a8d-euySgD.grib\n",
- "2017-01-05 10:28:36 Transfer rate 826.617 Kbytes/s\n",
- "2017-01-05 10:28:36 Done.\n"
- ]
- }
- ],
- "source": [
- "\n",
- "\n",
- "key = {\n",
- " \"url\" : \"https://api.ecmwf.int/v1\",\n",
- " \"key\" : \"83253855c912864513eb33f5fb1de322\",\n",
- " \"email\" : \"Sylvie.Lamy-Thepaut at ecmwf.int\"\n",
- " }\n",
- "\n",
- "request = {\n",
- " \"dataset\" : \"od\",\n",
- " \"class\" : \"od\",\n",
- " \"date\" : \"-1\",\n",
- " \"levtype\" : \"sfc\",\n",
- " \"param\" : \"167.128\",\n",
- " \"step\" : 6,\n",
- " \"type\" : \"fc\",\n",
- " \"time\" : 0,\n",
- " \"grid\" : [0.5,0.5]\n",
- " }\n",
- "\n",
- "mars = ECMWFService(\"mars\", **key) \n",
- "mars.execute(request, target)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd3wUdfoH8M/M9pbeC4QQSqhBqoAIYhf19NSfZ2+HiuWsIHiKqFhPRT0bnqJiB2woHmIB\nBOm9JARSSdtN2ZatszPz+2NgXbObTdgdpNzzfvnytezOPN/vfMvMk9mZWUYURRBCCCGEEPmwx7oC\nhBBCCCEnG0qwCCGEEEJkRgkWIYQQQojMKMEihBBCCJEZJViEEEIIITKjBIsQQgghRGaUYBFCCCGE\nyIwSLEIIIYQQmVGCRQghhBAiM0qwCCGEEEJkRgkWIYQQQojMKMEihBBCCJEZJViEEEIIITKjBIsQ\nQgghRGaUYBFCCCGEyIwSLEIIIYQQmVGCRQghhBAiM0qwCCGEEEJkRgkWIYQQQojMKMEihBBCCJEZ\nJViE [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "import Magics.macro as magics\n",
- "#Setting the coordinates of the geographical area\n",
- "projection = magics.mmap(subpage_map_projection = 'robinson',\n",
- " #subpage_lower_left_latitude= 34.,\n",
- " #subpage_lower_left_longitude= -40.,\n",
- " #subpage_upper_right_latitude= 60.,\n",
- " #subpage_upper_right_longitude= 24.\n",
- " )\n",
- "\n",
- "grib = magics.mgrib(grib_input_file_name=target)\n",
- "\n",
- "contour = magics.mcont(\n",
- " contour_automatic_setting=\"ecchart\",\n",
- " legend=\"on\"\n",
- ")\n",
- "\n",
- "title = magics.mtext()\n",
- "legend = magics.mlegend( legend_display_type = \"continuous\")\n",
- "\n",
- "magics.plot(projection, grib, contour, title, magics.mcoast(), legend)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/hcc.json b/notebook/hcc.json
deleted file mode 100644
index fc94179..0000000
--- a/notebook/hcc.json
+++ /dev/null
@@ -1,446 +0,0 @@
-{
- "api_version": "v1",
- "date": "20170103",
- "distance": {
- "angle": 328.378196018,
- "direction": "north-west",
- "distance": 1,
- "distance_unit": "km"
- },
- "ens_height": -0.357223510742,
- "ens_location": {
- "latitude": -57.9851531982,
- "longitude": 186.982757568
- },
- "expver": "0001",
- "hcc": {
- "control": [
- 0.0,
- 0.0,
- 0.0,
- 0.100006103516,
- 0.25,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.940002441406,
- 0.950012207031,
- 0.739990234375,
- 0.0499877929688,
- 0.989990234375,
- 0.989990234375,
- 0.839996337891,
- 0.399993896484,
- 0.649993896484,
- 0.989990234375,
- 0.959991455078,
- 0.899993896484,
- 0.0700073242188,
- 0.0,
- 0.980010986328,
- 0.619995117188,
- 0.0,
- 0.0,
- 0.0,
- 0.559997558594,
- 0.0,
- 0.0499877929688,
- 0.100006103516,
- 0.570007324219,
- 0.0,
- 0.0,
- 0.0,
- 0.959991455078,
- 1.0,
- 0.75,
- 0.140014648438,
- 0.239990234375
- ],
- "hres": [
- 0.0,
- 0.0,
- 0.0,
- 0.443237304688,
- 0.0986938476562,
- 0.226013183594,
- 0.971313476562,
- 0.981201171875,
- 0.985443115234,
- 0.977966308594,
- 0.323272705078,
- 0.656616210938,
- 1.0,
- 1.0,
- 0.0,
- 0.506561279297,
- 0.164093017578,
- 0.114654541016,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.961791992188,
- 0.890106201172,
- 0.524963378906,
- 0.812866210938,
- 0.0,
- 0.0,
- 0.00204467773438,
- 0.970001220703,
- 0.949981689453,
- 0.963348388672,
- 0.0,
- 0.0,
- 0.585144042969,
- 0.0,
- 0.0,
- 0.0635070800781,
- 0.190551757812,
- 0.980010986328
- ],
- "max": [
- 0.799987792969,
- 0.0,
- 0.609985351562,
- 0.970001220703,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0
- ],
- "median": [
- 0.0,
- 0.0,
- 0.0,
- 0.239990234375,
- 0.709991455078,
- 0.970001220703,
- 0.989990234375,
- 0.970001220703,
- 0.839996337891,
- 0.540008544922,
- 0.290008544922,
- 0.829986572266,
- 0.970001220703,
- 0.959991455078,
- 0.950012207031,
- 0.850006103516,
- 0.859985351562,
- 0.690002441406,
- 0.640014648438,
- 0.179992675781,
- 0.399993896484,
- 0.0599975585938,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0499877929688,
- 0.0,
- 0.0,
- 0.0400085449219,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.149993896484,
- 0.410003662109,
- 0.670013427734,
- 0.390014648438,
- 0.309997558594,
- 0.209991455078
- ],
- "min": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.010009765625,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "ninety": [
- 0.100006103516,
- 0.0,
- 0.220001220703,
- 0.679992675781,
- 0.970001220703,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.970001220703,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.959991455078,
- 0.899993896484,
- 0.910003662109,
- 0.890014648438,
- 0.920013427734,
- 0.799987792969,
- 0.980010986328,
- 0.950012207031,
- 1.0,
- 0.980010986328,
- 1.0,
- 0.950012207031,
- 0.959991455078,
- 0.859985351562,
- 0.980010986328,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0
- ],
- "seventy_five": [
- 0.0,
- 0.0,
- 0.0199890136719,
- 0.470001220703,
- 0.899993896484,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.970001220703,
- 0.839996337891,
- 0.970001220703,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.980010986328,
- 0.980010986328,
- 0.950012207031,
- 0.970001220703,
- 0.700012207031,
- 0.809997558594,
- 0.619995117188,
- 0.350006103516,
- 0.399993896484,
- 0.320007324219,
- 0.660003662109,
- 0.839996337891,
- 0.720001220703,
- 0.890014648438,
- 0.829986572266,
- 0.760009765625,
- 0.600006103516,
- 0.0299987792969,
- 0.390014648438,
- 0.980010986328,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375
- ],
- "steps": [
- "6",
- "12",
- "18",
- "24",
- "30",
- "36",
- "42",
- "48",
- "54",
- "60",
- "66",
- "72",
- "78",
- "84",
- "90",
- "96",
- "102",
- "108",
- "114",
- "120",
- "126",
- "132",
- "138",
- "144",
- "150",
- "156",
- "162",
- "168",
- "174",
- "180",
- "186",
- "192",
- "198",
- "204",
- "210",
- "216",
- "222",
- "228",
- "234",
- "240"
- ],
- "ten": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0400085449219,
- 0.790008544922,
- 0.5,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.119995117188,
- 0.0400085449219,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "twenty_five": [
- 0.0,
- 0.0,
- 0.0,
- 0.010009765625,
- 0.100006103516,
- 0.619995117188,
- 0.950012207031,
- 0.899993896484,
- 0.0199890136719,
- 0.0,
- 0.0299987792969,
- 0.140014648438,
- 0.519989013672,
- 0.779998779297,
- 0.709991455078,
- 0.230010986328,
- 0.480010986328,
- 0.0899963378906,
- 0.109985351562,
- 0.010009765625,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ]
- },
- "hres_height": -0.22412109375,
- "land_sea_mask": 0.0,
- "points_along_meridian": 1280,
- "time": "0000",
- "user_location": {
- "latitude": -58.0,
- "longitude": -173.0
- }
-}
\ No newline at end of file
diff --git a/notebook/lcc.json b/notebook/lcc.json
deleted file mode 100644
index 8dbee03..0000000
--- a/notebook/lcc.json
+++ /dev/null
@@ -1,446 +0,0 @@
-{
- "api_version": "v1",
- "date": "20161118",
- "distance": {
- "angle": 26.6096554983,
- "direction": "north-east",
- "distance": 8,
- "distance_unit": "km"
- },
- "ens_height": -0.0510711669922,
- "ens_location": {
- "latitude": 88.0670318604,
- "longitude": 190.0
- },
- "expver": "0001",
- "hres_height": 0.08154296875,
- "land_sea_mask": 0.0,
- "lcc": {
- "control": [
- 0.959991455078,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.950012207031,
- 0.980010986328,
- 0.980010986328,
- 0.989990234375,
- 1.0,
- 1.0,
- 1.0,
- 0.910003662109,
- 0.970001220703,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.980010986328,
- 0.989990234375,
- 0.910003662109,
- 0.839996337891,
- 0.980010986328,
- 0.950012207031,
- 1.0,
- 1.0,
- 0.959991455078,
- 0.959991455078,
- 0.989990234375,
- 1.0,
- 1.0,
- 1.0
- ],
- "hres": [
- 0.836456298828,
- 0.995849609375,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.923706054688,
- 0.945983886719,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.990600585938,
- 0.811706542969,
- 0.980743408203,
- 0.681121826172,
- 0.282531738281,
- 0.372772216797,
- 1.0,
- 0.159606933594,
- 1.0,
- 0.991546630859,
- 0.936981201172,
- 0.973358154297,
- 0.966461181641,
- 0.962524414062,
- 0.427642822266,
- 0.900451660156,
- 1.0,
- 1.0,
- 0.985260009766,
- 0.985229492188,
- 0.989471435547,
- 0.812133789062,
- 1.0
- ],
- "max": [
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0
- ],
- "median": [
- 0.980010986328,
- 0.989990234375,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375,
- 1.0,
- 0.989990234375,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.989990234375,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.989990234375,
- 0.989990234375,
- 1.0,
- 0.980010986328,
- 1.0,
- 0.989990234375,
- 0.980010986328
- ],
- "min": [
- 0.809997558594,
- 0.820007324219,
- 0.970001220703,
- 1.0,
- 0.920013427734,
- 0.880004882812,
- 0.5,
- 0.940002441406,
- 0.890014648438,
- 0.709991455078,
- 0.0199890136719,
- 0.390014648438,
- 0.239990234375,
- 0.540008544922,
- 0.899993896484,
- 0.839996337891,
- 0.720001220703,
- 0.809997558594,
- 0.609985351562,
- 0.730010986328,
- 0.0499877929688,
- 0.179992675781,
- 0.720001220703,
- 0.170013427734,
- 0.549987792969,
- 0.779998779297,
- 0.109985351562,
- 0.640014648438,
- 0.0799865722656,
- 0.670013427734,
- 0.829986572266,
- 0.540008544922,
- 0.649993896484,
- 0.589996337891,
- 0.399993896484,
- 0.579986572266,
- 0.290008544922,
- 0.209991455078,
- 0.470001220703,
- 0.489990234375
- ],
- "ninety": [
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0
- ],
- "seventy_five": [
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0
- ],
- "steps": [
- "6",
- "12",
- "18",
- "24",
- "30",
- "36",
- "42",
- "48",
- "54",
- "60",
- "66",
- "72",
- "78",
- "84",
- "90",
- "96",
- "102",
- "108",
- "114",
- "120",
- "126",
- "132",
- "138",
- "144",
- "150",
- "156",
- "162",
- "168",
- "174",
- "180",
- "186",
- "192",
- "198",
- "204",
- "210",
- "216",
- "222",
- "228",
- "234",
- "240"
- ],
- "ten": [
- 0.920013427734,
- 0.959991455078,
- 0.989990234375,
- 1.0,
- 0.970001220703,
- 0.959991455078,
- 0.959991455078,
- 0.989990234375,
- 0.980010986328,
- 0.980010986328,
- 0.910003662109,
- 0.690002441406,
- 0.799987792969,
- 0.940002441406,
- 0.940002441406,
- 0.959991455078,
- 0.899993896484,
- 0.929992675781,
- 0.929992675781,
- 0.790008544922,
- 0.910003662109,
- 0.700012207031,
- 0.920013427734,
- 0.790008544922,
- 0.920013427734,
- 0.950012207031,
- 0.769989013672,
- 0.880004882812,
- 0.660003662109,
- 0.929992675781,
- 0.920013427734,
- 0.720001220703,
- 0.779998779297,
- 0.839996337891,
- 0.760009765625,
- 0.799987792969,
- 0.730010986328,
- 0.799987792969,
- 0.839996337891,
- 0.799987792969
- ],
- "twenty_five": [
- 0.950012207031,
- 0.989990234375,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.989990234375,
- 0.989990234375,
- 1.0,
- 1.0,
- 1.0,
- 0.980010986328,
- 0.980010986328,
- 0.959991455078,
- 0.989990234375,
- 0.959991455078,
- 0.989990234375,
- 0.950012207031,
- 0.980010986328,
- 0.989990234375,
- 0.940002441406,
- 0.970001220703,
- 0.970001220703,
- 0.950012207031,
- 0.970001220703,
- 0.980010986328,
- 1.0,
- 0.959991455078,
- 0.959991455078,
- 0.950012207031,
- 0.980010986328,
- 0.970001220703,
- 0.970001220703,
- 0.910003662109,
- 0.929992675781,
- 0.940002441406,
- 0.929992675781,
- 0.929992675781,
- 0.970001220703,
- 0.970001220703,
- 0.920013427734
- ]
- },
- "points_along_meridian": 1280,
- "time": "0000",
- "user_location": {
- "latitude": 88.0,
- "longitude": -171.0
- }
-}
\ No newline at end of file
diff --git a/notebook/magics-netcdf.ipynb b/notebook/magics-netcdf.ipynb
deleted file mode 100644
index 30bae01..0000000
--- a/notebook/magics-netcdf.ipynb
+++ /dev/null
@@ -1,520 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# How to plot NetCDF Files with Magics\n",
- "\n",
- "This tutorial will give view an overview of the possibilities offered by Magics to interpret and plot some NetCDF data.\n",
- "\n",
- "You will have to create a netcdf object to help Magics to extract and interpret the data you want to plot. \n",
- "A list of the available parameters can be found in the <a href='https://software.ecmwf.int/wiki/display/MAGP/Netcdf+Input'> NetCDF Action Documentation</a><br>\n",
- "\n",
- "This action will be combined with a projection definition, and a visualisation action to create a plot.\n",
- "\n",
- "Magics can handle 2 type of geo-referenced NetCDF:\n",
- "<li> <b>geomatrix</b>: A geomatrix is a regular matrix, defined by 2 vectors [ 1 for latitudes, 1 for longitudes] </li>\n",
- "<li> <b>complex_matrix</b>: A complex_matrix is defined by 2 matrices [1 2D-Matrix describing the latitudes, and 1 2D-Matrix defining the longitudes] </li>\n",
- "\n",
- "But, let's try an example.\n",
- "\n",
- "We have NetCDF file : \n",
- "A simple ncdump will give the following information\n",
- "<pre>\n",
- "netcdf data {\n",
- "dimensions:\n",
- "\tlongitude = 360 ;\n",
- "\tlatitude = 181 ;\n",
- "\ttime = 1 ;\n",
- "variables:\n",
- "\t\tfloat longitude(longitude) ;\n",
- "\t\tlongitude:units = \"degrees_east\" ;\n",
- "\t\tlongitude:long_name = \"longitude\" ;\n",
- "\tfloat latitude(latitude) ;\n",
- "\t\tlatitude:units = \"degrees_north\" ;\n",
- "\t\tlatitude:long_name = \"latitude\" ;\n",
- "\tint level(level) ;\n",
- "\t\tlevel:units = \"millibars\" ;\n",
- "\t\tlevel:long_name = \"pressure_level\" ;\n",
- "\tint time(time) ;\n",
- "\t\ttime:units = \"hours since 1900-01-01 00:00:0.0\" ;\n",
- "\t\ttime:long_name = \"time\" ;\n",
- "\t\ttime:calendar = \"gregorian\" ;\n",
- "\tshort t(time, level, latitude, longitude) ;\n",
- "\t\tt:_FillValue = -32767s ;\n",
- "\t\tt:missing_value = -32767s ;\n",
- "\t\tt:units = \"K\" ;\n",
- "\t\tt:long_name = \"Temperature\" ;\n",
- "\t\tt:standard_name = \"air_temperature\", \n",
- "\n",
- "// global attributes:\n",
- "\t\t:Conventions = \"CF-1.6\" ;\n",
- "\t\t:history = \"2016-09-16 16:52:53 GMT by grib_to_netcdf-1.15.0\" ;\n",
- "}\n",
- "</pre>\n",
- "\n",
- "This simple example contains a regular field <i>t</i>, the geo-referencement is described by the 2 variables <i> latitude</i> and <i> longitude </i>.\n",
- "Let's pass this information to Magics through a <b>mnetcdf</b> object.\n",
- "\n",
- "\n",
- "First we import the Magics.macro package."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import Magics.macro as magics"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "Now, we have to define the geographical area we want to see in our final plot. Let's say that we focus on Europe in a geographical projection ..\n",
- "We need to create :\n",
- " <li> a <a href='https://software.ecmwf.int/wiki/display/MAGP/Subpage+-+Projection'> mmap object </a> to setup the geographical projection </li>\n",
- " <li> a <a href='https://software.ecmwf.int/wiki/display/MAGP/Coastlines'> mcoast object </a> to plot some coastlines </a> </li>\n",
- "\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "area = magics.mmap(\n",
- " subpage_map_projection = \"cylindrical\",\n",
- " subpage_lower_left_latitude = 30.00,\n",
- " subpage_lower_left_longitude = -20.00,\n",
- " subpage_upper_right_latitude = 60.00,\n",
- " subpage_upper_right_longitude = 20.00\n",
- ")\n",
- "\n",
- "coast = magics.mcoast(map_coastline_land_shade = \"on\",\n",
- " map_coastline_land_shade_colour = \"grey\",\n",
- " map_boundaries = \"on\",\n",
- " map_boundaries_colour = \"rgb(0.28,0.38,0.72)\",\n",
- " map_grid_latitude_increment = 5.00,\n",
- " map_grid_longitude_increment = 5.00\n",
- " )"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "Now that these 2 objects have been created, we combine them in a plot command :"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd0BT1/8//ptJ2ISwRxgyZCgIiAIORFwodaBoW61WbUvV8q7VqrXuVRWtvK0Dax3V9mNF\nWxeKIqIoyhAXoMgKG0IIAUL2ur8/7uebT36oGOCy7OvxV8bNvecaYp4595zXIaAoigAAAAAAAPwQ\n+7oBAAAAAAAfGghYAAAAAAA4g4AFAAAAAIAzCFgAAAAAADiDgAUAAAAAgDMIWAAAAAAAOIOABQAA\nAACAMwhYAAAAAAA4g4AFAAAAAIAzCFgAAAAAADiDgAUAAAAAgDMIWAAAAAAAOIOABQAAAACAMwhY\nAAAAAAA4g4AFAAAAAIAzCFgAAAAAADiDgAUAAAAAgDMIWAAAAAAAOIOABQAAAACAMwhYAAAAAAA4\ng4AF [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 22,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "magics.plot(area, coast)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "Note, that you have to define the area before anything else, this will allow Magics to setup its working environment and extract the relevant information from the data. \n",
- "You can experiment setting the area, and playing with the different options of the <i>mcoast</i> object.\n",
- "\n",
- "Now that you are happy, let's add our data: It important to define the name of the variable you want to extract from the NetCDF and the names of the variables that describe the geo-referencement. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 36,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "data = magics.mnetcdf(netcdf_type = \"geomatrix\",\n",
- " netcdf_filename = \"ERA5_00.nc\",\n",
- " netcdf_value_variable = \"t2m\",\n",
- " netcdf_dimension_setting = [\"time:2013-09:2015-12\"],\n",
- " netcdf_dimension_setting_method = \"value\", \n",
- " netcdf_latitude_variable = \"latitude\",\n",
- " netcdf_longitude_variable = \"longitude\"\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Next step is to define some visual attributes. To apply a contour, you have to create a <a href ='https://software.ecmwf.int/wiki/display/MAGP/Contouring' > mcont object </a>. This object comes with a long list of options to setup contour intervals, colour, shading, etc.\n",
- "We start simple by just changing the colour of the isolines. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 37,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "contour = magics.mcont(contour_line_colour = \"red\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To get a plot, we add these new objects into the plot command."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 38,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd1hTZ/sH8DuTsPfeyJCNgIioVUGr4N4drlZrrVpbq1Vr1dY6WkerP+tsXXW8fUVbtW6l\nuBAUnCBQVtgQIAQI2ev8/jhtXoqKAQ4Cen+uXr3IyRnPMQl8c87z3A+NIAhACCGEEELUoXd2AxBC\nCCGEXjUYsBBCCCGEKIYBCyGEEEKIYhiwEEIIIYQohgELIYQQQohiGLAQQgghhCiGAQshhBBCiGIY\nsBBCCCGEKIYBCyGEEEKIYhiwEEIIIYQohgELIYQQQohiGLAQQgghhCiGAQshhBBCiGIYsBBCCCGE\nKIYBCyGEEEKIYhiwEEIIIYQohgELIYQQQohiGLAQQgghhCiGAQshhBBCiGIYsBBCCCGEKIYBCyGE\nEEKI [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 38,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "magics.plot(area, coast, data, contour)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "What are this blue lines ? we asked for red! \n",
- "Magics has a concept of highlight isolines. Every nth isolines, Magics will use a different style/colour/thickness toplot the line.\n",
- "You can :\n",
- "<li> Turn that option off </li>"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 39,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd1gUV/s38HsrS++9I0U6AiJixwr2nmKLGmPUGI1GjVGjsSRGE/0Za2KL5ckjmoixK8GG\noGADRKQtHRZYFli2t3n/mLwbHlSkDAJ6f65cudjZmbNnXBa+zJxzHxpBEIAQQgghhKhD7+gOIIQQ\nQgi9bTBgIYQQQghRDAMWQgghhBDFMGAhhBBCCFEMAxZCCCGEEMUwYCGEEEIIUQwDFkIIIYQQxTBg\nIYQQQghRDAMWQgghhBDFMGAhhBBCCFEMAxZCCCGEEMUwYCGEEEIIUQwDFkIIIYQQxTBgIYQQQghR\nDAMWQgghhBDFMGAhhBBCCFEMAxZCCCGEEMUwYCGEEEIIUQwDFkIIIYQQxTBgIYQQQghRDAMWQggh\nhBDF [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 39,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "contour = magics.mcont(contour_line_colour = \"green\",\n",
- " contour_highlight = \"off\")\n",
- "magics.plot(area, coast, data, contour)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "<li>Or define your own highlight style</li>"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 40,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd2AT5R/H8XfSJt2T0tJBC2WXVfYSZIksAZmCAwREZQ8VnOAAJ0MFAVF/igiKKIrKcCEg\nQ/betFDopHSvpE3y+6ORUuhI2uvC7+uv5PLcc881Te6Tu+eeR2UymRBCCCGEEMpRV3QDhBBCCCHu\nNhKwhBBCCCEUJgFLCCGEEEJhErCEEEIIIRQmAUsIIYQQQmESsIQQQgghFCYBSwghhBBCYRKwhBBC\nCCEUJgFLCCGEEEJhErCEEEIIIRQmAUsIIYQQQmESsIQQQgghFCYBSwghhBBCYRKwhBBCCCEUJgFL\nCCGEEEJhErCEEEIIIRQmAUsIIYQQQmESsIQQQgghFCYBSwghhBBCYRKwhBBCCCEUJgFLCCGEEEJh\nErCE [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 40,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "contour = magics.mcont(contour_line_colour = \"red\",\n",
- " contour_highlight_colour = \"red\",\n",
- " contour_highlight_thickness = 2,\n",
- " contour='off',\n",
- " contour_shade = 'on', \n",
- " contour_shade_technique = \"grid_shading\",\n",
- " contour_shade_method = \"area_fill\")\n",
- "magics.plot(area, coast, data, contour, magics.mcoast())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Nice, but what about a title ?\n",
- "\n",
- "Easy, you can use an <a href='https://software.ecmwf.int/wiki/display/MAGP/Text+Plotting'> mtext object </a>.\n",
- "\n",
- "By default, the text will be positioned at the top of your plot."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 41,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "text = magics.mtext(text_lines = [\"A Netcdf Data is plotted\", \"The plot is <font color='red'> red </font>\"])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Add this new object to the plot command.."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 42,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdeXwkV3no/aeqelWrpdYy0kijGY1ms2ezxdg4xhhjcAwhGH9yTUjITYLzDgn3Bhu/r+PE\ncJ1c/ELA4LwJmAS/xJAEbIeEYMcYsA0J4OABY+Pd49k3z6J9aS2t3rur7h+SW62tp1t9WtXd+n0/\n80dX1elznuqWVM/UOXWOZlmWAAAAQB3d7gAAAACqDQkWAACAYiRYAAAAipFgAQAAKEaCBQAAoBgJ\nFgAAgGIkWAAAAIqRYAEAAChGggUAAKAYCRYAAIBiJFgAAACKkWABAAAoRoIFAACgGAkWAACAYiRY\nAAAAipFgAQAAKEaCBQAAoBgJFgAAgGIkWAAAAIqRYAEAAChGggUAAKAYCRYAAIBiJFgAAACKkWAB\nAAAo [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 42,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "magics.plot(area, coast, data, contour, text)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Good, but what if you want to extract some information from the NetCDF data ?\n",
- "\n",
- "Magics has a special tag <i>netcdf_info</i> that you can use to do that ..\n",
- "\n",
- "Imagine you want to display the standard name and the units of your variable, you can redefine your text object\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 43,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdeZxkdX3v/885p9auru7qfbqnmX0GZoN2AEVFRIkmKPq7mhhjNJLfeC8aGfmFa0IIJiFR\nJJKooJGfIeZGhSBEuaiA61UDg0T2ZZh96dl6X6rX2qvOuX90U1291VR1fatPVfXr+Zg/6pz61vd8\nqqq7z3vO+Z7v0SzLEgAAAKij210AAABApSFgAQAAKEbAAgAAUIyABQAAoBgBCwAAQDECFgAAgGIE\nLAAAAMUIWAAAAIoRsAAAABQjYAEAAChGwAIAAFCMgAUAAKAYAQsAAEAxAhYAAIBiBCwAAADFCFgA\nAACKEbAAAAAUI2ABAAAoRsACAABQjIAFAACgGAELAABAMQIWAACAYgQsAAAAxQhYAAAAihGwAAAA\nFCNg [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 43,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "text = magics.mtext(text_lines = [\"Using <b>netcdf_info</b> to tailor my title\", \n",
- " \"The field <netcdf_info variable='t' attribute='standard_name'/> is displayed in <netcdf_info variable='t' attribute='units'/>\"]\n",
- " )\n",
- "magics.plot(area, coast, data, contour, text)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's now explore another functionality : \n",
- "The variable we are displaying has four dimensions. \n",
- "t(time, level, latitude, longitude)\n",
- "The levels are 1000, 850, 500. \n",
- "By default Magics will "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 44,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdd1xTV/sA8JOQsKdsQZYIAjIERMUNLnDjbKvVqnVLtdZRrXVvW3ndE1etitaqoKhFFESm\nOABF9l4hBAhkj/v74/a9b34hxABh6fP99NNPcnPvuefce2Mezj33PCQMwxAAAAAAAFAecmdXAAAA\nAADgcwMBFgAAAACAkkGABQAAAACgZBBgAQAAAAAoGQRYAAAAAABKBgEWAAAAAICSQYAFAAAAAKBk\nEGABAAAAACgZBFgAAAAAAEoGARYAAAAAgJJBgAUAAAAAoGQQYAEAAAAAKBkEWAAAAAAASgYBFgAA\nAACAkkGABQAAAACgZBBgAQAAAAAoGQRYAAAAAABKBgEWAAAAAICSQYAFAAAAAKBkEGABAAAAACgZ\nBFgA [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 44,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "data = magics.mnetcdf(netcdf_type = \"geomatrix\",\n",
- " netcdf_filename = \"data.nc\",\n",
- " netcdf_value_variable = \"t\",\n",
- " netcdf_latitude_variable = \"latitude\",\n",
- " netcdf_longitude_variable = \"longitude\",\n",
- " netcdf_dimension_setting = [\"latitude:40:50\"]\n",
- ")\n",
- "text = magics.mtext(text_lines = [\"Using <b>netcdf_dimension_setting</b> extract a subse of the data\", \n",
- " \"Here we only display the data between 40° and 50° North\"]\n",
- " )\n",
- "magics.plot(area, coast, data, contour, text)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Here trying the same with the toolbox \n",
- "\n",
- "### First , import the toolbox\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 45,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import Magics.toolbox as toolbox"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Creating a geoplot\n",
- "This will auotomatical set up a geographical view"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 46,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdeZwcZZ0/8G/dR98995GZ3JmckEC45AqgCCIi7k/dhRUERUVdXXXXFc9VOfbn4r0/0XXF\nW1ZBV1F05T40nElIgCRMzrmvnr6qu+56fn9U0gw5JpOkkgnJ501evKZrquv7VHVN96ernnqKY4wR\nAAAAAESHn+4GAAAAABxvELAAAAAAIoaABQAAABAxBCwAAACAiCFgAQAAAEQMAQsAAAAgYghYAAAA\nABFDwAIAAACIGAIWAAAAQMQQsAAAAAAihoAFAAAAEDEELAAAAICIIWABAAAARAwBCwAAACBiCFgA\nAAAAEUPAAgAAAIgYAhYAAABAxBCwAAAAACKGgAUAAAAQMQQsAAAAgIghYAEAAABEDAELAAAAIGII\nWAAA [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 46,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "\n",
- "data = magics.mnetcdf(netcdf_type = \"geomatrix\",\n",
- " netcdf_filename = \"data.nc\",\n",
- " netcdf_value_variable = \"t\",\n",
- " netcdf_latitude_variable = \"latitude\",\n",
- " netcdf_longitude_variable = \"longitude\",\n",
- ")\n",
- "\n",
- "toolbox.geoplot(data, title = [\"Playing with automatic setting!\"])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/magics1.ipynb b/notebook/magics1.ipynb
deleted file mode 100644
index c6c4eb4..0000000
--- a/notebook/magics1.ipynb
+++ /dev/null
@@ -1,226 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['CONTOURS',\n",
- " 'Image',\n",
- " 'LOCK',\n",
- " 'ONOFF',\n",
- " 'PROJECTIONS',\n",
- " '__builtins__',\n",
- " '__doc__',\n",
- " '__file__',\n",
- " '__name__',\n",
- " '__package__',\n",
- " '__path__',\n",
- " '_plot',\n",
- " 'json',\n",
- " 'macro',\n",
- " 'myplot',\n",
- " 'np',\n",
- " 'os',\n",
- " 'tempfile',\n",
- " 'threading',\n",
- " 'x',\n",
- " 'xplot']"
- ]
- },
- "execution_count": 1,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "import maps\n",
- "\n",
- "dir(maps)\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "3"
- ]
- },
- "execution_count": 1,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "1+2\n",
- "\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "from Magics import macro\n",
- "\n",
- "\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "\n",
- "x = macro.output(output_formats=[\"png\"],\n",
- " output_name_first_page_number='off',\n",
- " output_name=\"x\")\n",
- "macro.plot(x, macro.mcoast())\n",
- "\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "ename": "ImportError",
- "evalue": "No module named maps",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-4-26013ff84beb>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mmaps\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mMagics\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmacro\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0; [...]
- "\u001b[0;31mImportError\u001b[0m: No module named maps"
- ]
- }
- ],
- "source": [
- "import maps\n",
- "from Magics import macro\n",
- "\n",
- "\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "LENGTH 2\n",
- "/var/folders/_d/7kx7p7sj7qjfnhmn1hn3sqwh0000gr/T/tmpFEQXqg.png\n",
- "/var/folders/_d/7kx7p7sj7qjfnhmn1hn3sqwh0000gr/T/tmpFEQXqg\n"
- ]
- },
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAI2CAIAAAAn6nsNAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzdeXhcZd0+8PvMnlmSyb40aZq1TbqFpjsUKK0CBQVKFQUVQX1ZRIRXgQr6ggv1FUHbV5Yi\nCFp+SBFRNtlKaUvpAl2S7k3SbM2+z5LZl/P7Y9J0kkwmk+Qkacr9ubi4pjMn85xJzszc5znP830E\nURRBRERERNKRTfQOEBEREZ1vGLCIiIiIJMaARURERCQxBiwiIiIiiTFgEREREUmMAYuIiIhIYgxY\nRERERBJjwCIiIiKSGAMWERERkcQYsIiIiIgkxoBFREREJDEGLCIiIiKJMWARERERSYwBi4iIiEhi\nDFhEREREEmPAIiIiIpIYAxYRERGRxBiwiIiIiCTGgEVEREQkMQYsIiIiIokxYBERERFJjAGLiIiI\nSGIM [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "\n",
- "maps.myplot(macro.mcoast(map_coastline_land_shade = \"on\",\n",
- " map_coastline_land_shade_colour = \"rgb(0.65,0.32,0.32)\"), \n",
- " macro.mcoast(\n",
- " map_coastline_colour = \"red\",\n",
- " map_coastline_thickness = 10\n",
- "))\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAIAAAAP3aGbAAAABmJLR0QA/wD/AP+gvaeTAAAgAElE\nQVR4nOzddXxT1/8/8BN3bVJ3od5SWijF3X2wocPd2djGYMMGQ4c7DAYDhgwoMmC4S1vq7pJKGk8a\nv8nvj/DtcAp8Pt997+/xfv6xlZt7T869SV6598gNoUOHDn5+fggAAP5vKy0tJYeEhOzZs+ffrgkA\nALzH1KlTif92HQAAoKkgsAAAuAGBBQDADQgsAABuQGABAHADAgsAgBsQWAAA3IDAAgDgBgQWAAA3\nILAAALgBgQUAwA0ILAAAbkBgAQBwAwILAIAbEFgAANyAwAIA4AYEFgAANyCwAAC4AYEFAMANCCwA\nAG5AYAEAcAMCCwCAGxBYAADcgMACAOAGBBYAADcgsAAAuAGBBQDADQgsAABuQGABAHADAgsAgBsQ\nWAAA [...]
- "text/plain": [
- "<IPython.core.display.Image object>"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "maps.plot(\"data.grib\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/mcc.json b/notebook/mcc.json
deleted file mode 100644
index 5a66ccb..0000000
--- a/notebook/mcc.json
+++ /dev/null
@@ -1,446 +0,0 @@
-{
- "api_version": "v1",
- "date": "20170103",
- "distance": {
- "angle": 180.0,
- "direction": "south",
- "distance": 7,
- "distance_unit": "km"
- },
- "ens_height": 1578.64428711,
- "ens_location": {
- "latitude": 34.9316635132,
- "longitude": 60.0
- },
- "expver": "0001",
- "hres_height": 1743.50683594,
- "land_sea_mask": 1.0,
- "mcc": {
- "control": [
- 0.320007324219,
- 0.0899963378906,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.980010986328,
- 0.0199890136719,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0299987792969,
- 0.790008544922,
- 0.209991455078,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "hres": [
- 0.18212890625,
- 0.151641845703,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.683410644531,
- 0.0665588378906,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.926025390625,
- 0.04736328125,
- 0.0,
- 0.0,
- 0.0,
- 0.881134033203,
- 0.0943298339844,
- 0.736480712891,
- 0.0,
- 0.0
- ],
- "max": [
- 0.970001220703,
- 0.910003662109,
- 0.0,
- 0.0,
- 0.0,
- 0.25,
- 0.170013427734,
- 0.859985351562,
- 0.420013427734,
- 1.0,
- 0.429992675781,
- 0.0299987792969,
- 0.0,
- 0.890014648438,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.209991455078,
- 0.130004882812,
- 0.540008544922,
- 0.679992675781,
- 0.0400085449219,
- 0.529998779297,
- 0.0,
- 0.0199890136719,
- 0.929992675781,
- 0.779998779297,
- 1.0,
- 0.940002441406,
- 1.0,
- 1.0,
- 0.950012207031,
- 0.739990234375,
- 0.959991455078,
- 0.959991455078,
- 1.0,
- 1.0,
- 0.980010986328,
- 1.0
- ],
- "median": [
- 0.5,
- 0.0799865722656,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.720001220703,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "min": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "ninety": [
- 0.880004882812,
- 0.320007324219,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.010009765625,
- 1.0,
- 0.230010986328,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0499877929688,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.429992675781,
- 0.0599975585938,
- 0.0299987792969,
- 0.959991455078,
- 0.790008544922,
- 0.399993896484,
- 0.25,
- 0.0899963378906,
- 0.279998779297,
- 0.25,
- 0.700012207031,
- 0.209991455078,
- 0.0799865722656
- ],
- "seventy_five": [
- 0.720001220703,
- 0.160003662109,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.970001220703,
- 0.010009765625,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.369995117188,
- 0.140014648438,
- 0.0899963378906,
- 0.010009765625,
- 0.0,
- 0.010009765625,
- 0.0,
- 0.260009765625,
- 0.0,
- 0.0
- ],
- "steps": [
- "6",
- "12",
- "18",
- "24",
- "30",
- "36",
- "42",
- "48",
- "54",
- "60",
- "66",
- "72",
- "78",
- "84",
- "90",
- "96",
- "102",
- "108",
- "114",
- "120",
- "126",
- "132",
- "138",
- "144",
- "150",
- "156",
- "162",
- "168",
- "174",
- "180",
- "186",
- "192",
- "198",
- "204",
- "210",
- "216",
- "222",
- "228",
- "234",
- "240"
- ],
- "ten": [
- 0.0299987792969,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "twenty_five": [
- 0.109985351562,
- 0.010009765625,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.299987792969,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ]
- },
- "points_along_meridian": 1280,
- "time": "0000",
- "user_location": {
- "latitude": 35.0,
- "longitude": 60.0
- }
-}
\ No newline at end of file
diff --git a/notebook/mongo.ipynb b/notebook/mongo.ipynb
deleted file mode 100644
index 0e79a6c..0000000
--- a/notebook/mongo.ipynb
+++ /dev/null
@@ -1,217 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import pymongo\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "from pymongo import MongoClient\n",
- "client = MongoClient()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{'param2': 'val2', 'param1': 'val1'}\n"
- ]
- }
- ],
- "source": [
- "stat = { \"param1\" : \"val1\", \"param2\" : \"val2\" }\n",
- "print stat "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "<pymongo.results.InsertOneResult at 0x10849bb40>"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "db = client['statistique']\n",
- "stats = db.stats\n",
- "stats.insert_one(stat)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{u'_id': ObjectId('57d86ce2049832a4a0ddd19b'),\n",
- " u'param1': u'val1',\n",
- " u'param2': u'val2'}"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "stats.find_one()\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 30,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{'name': 'stat', 'value': 1}\n",
- "{'name': 'stat', 'value': 2}\n",
- "{'name': 'stat', 'value': 3}\n",
- "{'name': 'stat', 'value': 4}\n",
- "{'name': 'stat', 'value': 5}\n",
- "{'name': 'stat', 'value': 6}\n",
- "{'name': 'stat', 'value': 7}\n",
- "{'name': 'stat', 'value': 8}\n",
- "{'name': 'stat', 'value': 9}\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "46"
- ]
- },
- "execution_count": 30,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "\n",
- "for i in range(1, 10):\n",
- " stat = {}\n",
- " stat[\"name\"] = \"stat\"\n",
- " stat[\"value\"] = i\n",
- " print stat\n",
- " db.stats.insert_one(stat)\n",
- " \n",
- "db.stats.count()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 36,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 36,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "ex = db.stats.find({\"value\" : 3})\n",
- "db.stats.count({\"value\" : 3})\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 37,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{u'_id': ObjectId('57d87097049832a4a0ddd19f'), u'name': u'stat', u'value': 3}\n",
- "{u'_id': ObjectId('57d870aa049832a4a0ddd1a8'), u'name': u'stat', u'value': 3}\n",
- "{u'_id': ObjectId('57d870b2049832a4a0ddd1b1'), u'name': u'stat', u'value': 3}\n",
- "{u'_id': ObjectId('57d870b8049832a4a0ddd1ba'), u'name': u'stat', u'value': 3}\n",
- "{u'_id': ObjectId('57d8713d049832a4a0ddd1c3'), u'name': u'stat', u'value': 3}\n"
- ]
- }
- ],
- "source": [
- "for e in ex:\n",
- " print e"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/notebook/read.py b/notebook/read.py
deleted file mode 100644
index 09cb340..0000000
--- a/notebook/read.py
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-import json
-import datetime
-import pprint
-import numpy as np
-
-with open('2t.json') as json_data:
- d = json.load(json_data)
-
-
-
-
-data = d["2t"]
-
-print d["date"]
-start = datetime.datetime.strptime(d["date"], "%Y%m%d")
-start = start + datetime.timedelta(hours=48)
-print start.strftime("ixxx%Y%m%d")
-
-steps = map(lambda x : start + datetime.timedelta(hours=int(x)), data["steps"])
-steps = map(lambda x : x.strftime("%Y-%m-%d %H:%M"), steps)
-val = map(lambda x : x -273.15, data["median"])
-np.set_printoptions(precision=2)
-
-print repr(np.array(val))
-
diff --git a/notebook/sf.json b/notebook/sf.json
deleted file mode 100644
index 61246fc..0000000
--- a/notebook/sf.json
+++ /dev/null
@@ -1,446 +0,0 @@
-{
- "api_version": "v1",
- "date": "20161118",
- "distance": {
- "angle": 313.38212199,
- "direction": "north-west",
- "distance": 5,
- "distance_unit": "km"
- },
- "ens_height": 757.543151855,
- "ens_location": {
- "latitude": -23.9671974182,
- "longitude": 131.962020874
- },
- "expver": "0001",
- "hres_height": 773.883789062,
- "land_sea_mask": 1.0,
- "points_along_meridian": 1280,
- "sf": {
- "control": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "hres": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "max": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "median": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "min": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "ninety": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "seventy_five": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "steps": [
- "6",
- "12",
- "18",
- "24",
- "30",
- "36",
- "42",
- "48",
- "54",
- "60",
- "66",
- "72",
- "78",
- "84",
- "90",
- "96",
- "102",
- "108",
- "114",
- "120",
- "126",
- "132",
- "138",
- "144",
- "150",
- "156",
- "162",
- "168",
- "174",
- "180",
- "186",
- "192",
- "198",
- "204",
- "210",
- "216",
- "222",
- "228",
- "234",
- "240"
- ],
- "ten": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "twenty_five": [
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ]
- },
- "time": "0000",
- "user_location": {
- "latitude": -24.0,
- "longitude": 132.0
- }
-}
\ No newline at end of file
diff --git a/notebook/tcc.json b/notebook/tcc.json
deleted file mode 100644
index f1d6647..0000000
--- a/notebook/tcc.json
+++ /dev/null
@@ -1,446 +0,0 @@
-{
- "api_version": "v1",
- "date": "20170103",
- "distance": {
- "angle": 70.4883862641,
- "direction": "east",
- "distance": 1,
- "distance_unit": "km"
- },
- "ens_height": 0.458694458008,
- "ens_location": {
- "latitude": -30.9957027435,
- "longitude": 246.014144897
- },
- "expver": "0001",
- "hres_height": -0.02001953125,
- "land_sea_mask": 0.0,
- "points_along_meridian": 1280,
- "tcc": {
- "control": [
- 1.0,
- 0.609985351562,
- 1.0,
- 1.0,
- 1.0,
- 0.920013427734,
- 1.0,
- 0.980010986328,
- 0.920013427734,
- 0.309997558594,
- 0.980010986328,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.619995117188,
- 1.0,
- 0.959991455078,
- 0.0400085449219,
- 0.0,
- 0.0,
- 0.170013427734,
- 0.0700073242188,
- 0.470001220703,
- 0.609985351562,
- 0.989990234375,
- 1.0,
- 0.600006103516,
- 0.529998779297,
- 0.279998779297,
- 0.980010986328,
- 0.339996337891,
- 0.0799865722656,
- 0.579986572266,
- 0.339996337891,
- 0.720001220703,
- 0.570007324219
- ],
- "hres": [
- 0.934356689453,
- 0.735229492188,
- 0.963134765625,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.612060546875,
- 0.594665527344,
- 0.971099853516,
- 0.214538574219,
- 0.927307128906,
- 1.0,
- 1.0,
- 1.0,
- 0.997222900391,
- 1.0,
- 1.0,
- 0.998840332031,
- 0.997680664062,
- 0.672790527344,
- 0.199645996094,
- 0.34912109375,
- 0.450836181641,
- 0.345031738281,
- 0.355072021484,
- 0.078369140625,
- 0.232879638672,
- 0.992767333984,
- 0.989990234375,
- 1.0,
- 1.0,
- 0.992767333984,
- 0.657592773438,
- 0.433013916016,
- 0.82470703125,
- 0.977142333984,
- 0.959716796875,
- 0.551055908203,
- 0.8310546875,
- 1.0
- ],
- "max": [
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0
- ],
- "median": [
- 0.989990234375,
- 0.970001220703,
- 0.980010986328,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.989990234375,
- 0.859985351562,
- 0.440002441406,
- 0.950012207031,
- 0.980010986328,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.950012207031,
- 0.959991455078,
- 0.410003662109,
- 0.429992675781,
- 0.329986572266,
- 0.390014648438,
- 0.420013427734,
- 0.459991455078,
- 0.519989013672,
- 0.649993896484,
- 0.75,
- 0.910003662109,
- 0.959991455078,
- 0.929992675781,
- 0.579986572266,
- 0.880004882812,
- 0.880004882812,
- 0.940002441406,
- 0.859985351562,
- 0.980010986328,
- 0.850006103516,
- 0.790008544922,
- 0.670013427734,
- 0.570007324219
- ],
- "min": [
- 0.720001220703,
- 0.239990234375,
- 0.0299987792969,
- 0.230010986328,
- 0.940002441406,
- 0.390014648438,
- 0.609985351562,
- 0.010009765625,
- 0.0,
- 0.0,
- 0.0,
- 0.0799865722656,
- 0.529998779297,
- 0.779998779297,
- 0.75,
- 0.140014648438,
- 0.0,
- 0.010009765625,
- 0.0,
- 0.0,
- 0.010009765625,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0400085449219,
- 0.0,
- 0.160003662109,
- 0.0,
- 0.0,
- 0.0299987792969,
- 0.0199890136719,
- 0.0499877929688,
- 0.0,
- 0.010009765625,
- 0.0,
- 0.0400085449219,
- 0.0,
- 0.0
- ],
- "ninety": [
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.950012207031,
- 1.0,
- 0.970001220703,
- 0.989990234375,
- 0.980010986328,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0
- ],
- "seventy_five": [
- 1.0,
- 0.989990234375,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.859985351562,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 1.0,
- 0.940002441406,
- 0.820007324219,
- 0.760009765625,
- 0.670013427734,
- 0.880004882812,
- 0.730010986328,
- 0.869995117188,
- 0.940002441406,
- 0.970001220703,
- 0.989990234375,
- 1.0,
- 0.980010986328,
- 1.0,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.989990234375,
- 1.0,
- 0.950012207031,
- 0.970001220703,
- 0.970001220703,
- 0.950012207031
- ],
- "steps": [
- "6",
- "12",
- "18",
- "24",
- "30",
- "36",
- "42",
- "48",
- "54",
- "60",
- "66",
- "72",
- "78",
- "84",
- "90",
- "96",
- "102",
- "108",
- "114",
- "120",
- "126",
- "132",
- "138",
- "144",
- "150",
- "156",
- "162",
- "168",
- "174",
- "180",
- "186",
- "192",
- "198",
- "204",
- "210",
- "216",
- "222",
- "228",
- "234",
- "240"
- ],
- "ten": [
- 0.859985351562,
- 0.459991455078,
- 0.390014648438,
- 0.989990234375,
- 0.989990234375,
- 0.600006103516,
- 0.700012207031,
- 0.109985351562,
- 0.010009765625,
- 0.170013427734,
- 0.839996337891,
- 0.609985351562,
- 0.959991455078,
- 0.980010986328,
- 0.980010986328,
- 0.929992675781,
- 0.0599975585938,
- 0.190002441406,
- 0.109985351562,
- 0.0499877929688,
- 0.0400085449219,
- 0.0799865722656,
- 0.0499877929688,
- 0.0400085449219,
- 0.140014648438,
- 0.0799865722656,
- 0.190002441406,
- 0.170013427734,
- 0.260009765625,
- 0.149993896484,
- 0.119995117188,
- 0.119995117188,
- 0.279998779297,
- 0.209991455078,
- 0.100006103516,
- 0.239990234375,
- 0.0799865722656,
- 0.119995117188,
- 0.0899963378906,
- 0.0199890136719
- ],
- "twenty_five": [
- 0.950012207031,
- 0.829986572266,
- 0.869995117188,
- 1.0,
- 1.0,
- 0.940002441406,
- 0.940002441406,
- 0.429992675781,
- 0.25,
- 0.730010986328,
- 0.940002441406,
- 0.950012207031,
- 0.989990234375,
- 1.0,
- 1.0,
- 0.989990234375,
- 0.329986572266,
- 0.480010986328,
- 0.25,
- 0.160003662109,
- 0.149993896484,
- 0.140014648438,
- 0.230010986328,
- 0.130004882812,
- 0.369995117188,
- 0.279998779297,
- 0.359985351562,
- 0.529998779297,
- 0.739990234375,
- 0.589996337891,
- 0.329986572266,
- 0.359985351562,
- 0.440002441406,
- 0.410003662109,
- 0.380004882812,
- 0.640014648438,
- 0.299987792969,
- 0.399993896484,
- 0.329986572266,
- 0.350006103516
- ]
- },
- "time": "0000",
- "user_location": {
- "latitude": -31.0,
- "longitude": -114.0
- }
-}
\ No newline at end of file
diff --git a/notebook/tp.json b/notebook/tp.json
deleted file mode 100644
index 6765964..0000000
--- a/notebook/tp.json
+++ /dev/null
@@ -1,446 +0,0 @@
-{
- "api_version": "v1",
- "date": "20161121",
- "distance": {
- "angle": 277.14499032,
- "direction": "west",
- "distance": 7,
- "distance_unit": "km"
- },
- "ens_height": -0.255172729492,
- "ens_location": {
- "latitude": 39.0081977844,
- "longitude": 222.915527344
- },
- "expver": "0001",
- "hres_height": -0.326171875,
- "land_sea_mask": 0.0,
- "points_along_meridian": 1280,
- "time": "0000",
- "tp": {
- "control": [
- 0.000270843505859,
- 0.000141143798828,
- 0.000518798828125,
- 0.000450134277344,
- 0.000827789306641,
- 0.000267028808594,
- 0.000499725341797,
- 0.000637054443359,
- 0.000282287597656,
- 0.000389099121094,
- 0.000354766845703,
- 1.90734863281e-05,
- 0.000267028808594,
- 9.91821289062e-05,
- 0.00303649902344,
- 0.00102615356445,
- 0.00116729736328,
- 0.000900268554688,
- 0.000213623046875,
- 0.000244140625,
- 0.000473022460938,
- 0.000923156738281,
- 0.000656127929688,
- 0.000717163085938,
- 0.000411987304688,
- 0.000267028808594,
- 0.000267028808594,
- 0.000343322753906,
- 7.62939453125e-05,
- 0.0,
- 0.0,
- 0.0,
- 7.62939453125e-06,
- 6.86645507812e-05,
- 0.000244140625,
- 0.00433349609375,
- 0.000320434570312,
- 0.00102233886719,
- 7.62939453125e-06,
- 3.81469726562e-05
- ],
- "hres": [
- 0.000101089477539,
- 0.000238418579102,
- 0.00037956237793,
- 0.000432968139648,
- 0.000892639160156,
- 0.00050163269043,
- 0.000783920288086,
- 0.000448226928711,
- 0.000288009643555,
- 0.000205993652344,
- 0.000102996826172,
- 5.72204589844e-05,
- 0.000251770019531,
- 0.000106811523438,
- 0.00178146362305,
- 0.00114822387695,
- 0.00165557861328,
- 0.000259399414062,
- 0.0,
- 0.0,
- 0.000648498535156,
- 0.000534057617188,
- 0.000633239746094,
- 0.000335693359375,
- 0.00130081176758,
- 0.000137329101562,
- 0.000141143798828,
- 6.103515625e-05,
- 2.28881835938e-05,
- 0.000106811523438,
- 0.0001220703125,
- 9.1552734375e-05,
- 7.62939453125e-06,
- 7.62939453125e-06,
- 6.103515625e-05,
- 0.000877380371094,
- 2.28881835938e-05,
- 0.000106811523438,
- 0.000175476074219,
- 0.000129699707031
- ],
- "max": [
- 0.000699996948242,
- 0.000725746154785,
- 0.00267028808594,
- 0.0020923614502,
- 0.00249862670898,
- 0.00155639648438,
- 0.00202941894531,
- 0.00203323364258,
- 0.00112533569336,
- 0.0010871887207,
- 0.000953674316406,
- 0.00106811523438,
- 0.00506210327148,
- 0.00722503662109,
- 0.00812530517578,
- 0.00875091552734,
- 0.00563049316406,
- 0.00729370117188,
- 0.00222778320312,
- 0.00374603271484,
- 0.00316619873047,
- 0.00254821777344,
- 0.00209808349609,
- 0.00459289550781,
- 0.0015869140625,
- 0.00393676757812,
- 0.00229644775391,
- 0.000442504882812,
- 0.000328063964844,
- 0.000923156738281,
- 0.000457763671875,
- 0.00111389160156,
- 0.00333404541016,
- 0.00559997558594,
- 0.0145034790039,
- 0.00304412841797,
- 0.00856781005859,
- 0.00804138183594,
- 0.00534057617188,
- 0.00079345703125
- ],
- "median": [
- 0.000175476074219,
- 0.000114440917969,
- 0.000463485717773,
- 0.000705718994141,
- 0.000801086425781,
- 0.000434875488281,
- 0.000495910644531,
- 0.000503540039062,
- 0.000152587890625,
- 0.000232696533203,
- 0.0001220703125,
- 0.000114440917969,
- 0.000453948974609,
- 0.000701904296875,
- 0.00135040283203,
- 0.00160217285156,
- 0.000694274902344,
- 0.000324249267578,
- 0.000129699707031,
- 0.000152587890625,
- 8.39233398438e-05,
- 0.000106811523438,
- 0.00018310546875,
- 0.000106811523438,
- 0.000114440917969,
- 0.000152587890625,
- 0.000167846679688,
- 4.57763671875e-05,
- 2.28881835938e-05,
- 0.0,
- 0.0,
- 0.0,
- 1.52587890625e-05,
- 5.34057617188e-05,
- 0.000175476074219,
- 0.000251770019531,
- 0.000114440917969,
- 6.103515625e-05,
- 7.62939453125e-06,
- 0.0
- ],
- "min": [
- 0.0,
- 0.0,
- 0.00010871887207,
- 9.1552734375e-05,
- 3.81469726562e-06,
- 5.34057617188e-05,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- -3.81469726562e-06,
- 0.0,
- 0.0,
- 0.000118255615234,
- 3.81469726562e-06,
- 0.0,
- 0.0,
- 0.0,
- -3.81469726562e-06,
- 0.0,
- 0.0,
- 0.0,
- -7.62939453125e-06,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- -7.62939453125e-06,
- -7.62939453125e-06,
- -7.62939453125e-06,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "ninety": [
- 0.000448226928711,
- 0.000400543212891,
- 0.00117111206055,
- 0.00146865844727,
- 0.00156402587891,
- 0.000957489013672,
- 0.000900268554688,
- 0.00128936767578,
- 0.000442504882812,
- 0.000602722167969,
- 0.000614166259766,
- 0.000408172607422,
- 0.00114440917969,
- 0.00299835205078,
- 0.00374603271484,
- 0.00389862060547,
- 0.00371551513672,
- 0.00131988525391,
- 0.000892639160156,
- 0.000526428222656,
- 0.000770568847656,
- 0.000762939453125,
- 0.000892639160156,
- 0.000869750976562,
- 0.00042724609375,
- 0.000877380371094,
- 0.000579833984375,
- 0.000251770019531,
- 0.000228881835938,
- 0.000236511230469,
- 0.000259399414062,
- 0.000213623046875,
- 0.000251770019531,
- 0.00135803222656,
- 0.00212097167969,
- 0.00130462646484,
- 0.00129699707031,
- 0.000526428222656,
- 0.00111389160156,
- 0.000267028808594
- ],
- "seventy_five": [
- 0.000286102294922,
- 0.000202178955078,
- 0.000654220581055,
- 0.00103950500488,
- 0.00118064880371,
- 0.000686645507812,
- 0.000785827636719,
- 0.000808715820312,
- 0.00030517578125,
- 0.000396728515625,
- 0.000370025634766,
- 0.000278472900391,
- 0.000843048095703,
- 0.00157928466797,
- 0.00232696533203,
- 0.00290679931641,
- 0.0015869140625,
- 0.000823974609375,
- 0.000473022460938,
- 0.000282287597656,
- 0.000335693359375,
- 0.000373840332031,
- 0.000312805175781,
- 0.000404357910156,
- 0.00030517578125,
- 0.000495910644531,
- 0.000289916992188,
- 0.000152587890625,
- 9.1552734375e-05,
- 0.000106811523438,
- 0.000160217285156,
- 7.62939453125e-05,
- 0.000106811523438,
- 0.000335693359375,
- 0.00048828125,
- 0.000534057617188,
- 0.000511169433594,
- 0.000274658203125,
- 0.000228881835938,
- 3.81469726562e-05
- ],
- "steps": [
- "6",
- "12",
- "18",
- "24",
- "30",
- "36",
- "42",
- "48",
- "54",
- "60",
- "66",
- "72",
- "78",
- "84",
- "90",
- "96",
- "102",
- "108",
- "114",
- "120",
- "126",
- "132",
- "138",
- "144",
- "150",
- "156",
- "162",
- "168",
- "174",
- "180",
- "186",
- "192",
- "198",
- "204",
- "210",
- "216",
- "222",
- "228",
- "234",
- "240"
- ],
- "ten": [
- 1.52587890625e-05,
- 3.0517578125e-05,
- 0.000221252441406,
- 0.000263214111328,
- 0.000175476074219,
- 0.000152587890625,
- 0.000133514404297,
- 3.0517578125e-05,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 4.57763671875e-05,
- 0.000106811523438,
- 0.000255584716797,
- 0.000442504882812,
- 0.000144958496094,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 7.62939453125e-06,
- 3.0517578125e-05,
- 1.52587890625e-05,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ],
- "twenty_five": [
- 7.82012939453e-05,
- 6.29425048828e-05,
- 0.000284194946289,
- 0.000503540039062,
- 0.000492095947266,
- 0.000255584716797,
- 0.000255584716797,
- 0.000236511230469,
- 3.0517578125e-05,
- 1.90734863281e-05,
- 2.28881835938e-05,
- 1.52587890625e-05,
- 0.000263214111328,
- 0.000396728515625,
- 0.000583648681641,
- 0.000839233398438,
- 0.000343322753906,
- 5.72204589844e-05,
- 3.0517578125e-05,
- 0.0,
- 3.81469726562e-06,
- 0.0,
- 0.0,
- 0.0,
- 4.57763671875e-05,
- 6.103515625e-05,
- 7.62939453125e-05,
- 1.52587890625e-05,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 3.0517578125e-05,
- 3.81469726562e-05,
- 1.52587890625e-05,
- 0.0,
- 0.0,
- 0.0
- ]
- },
- "user_location": {
- "latitude": 39.0,
- "longitude": -137.0
- }
-}
\ No newline at end of file
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 1548ba5..2d898e7 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,7 +1,10 @@
if( HAVE_PYTHON )
configure_file( setup.py.in setup.py )
- configure_file( Magics.py.in Magics/Magics.py )
+ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../src/common/magics_api.h magics_api.h COPYONLY )
+ configure_file( numpy.i numpy.i COPYONLY )
+ configure_file( Magics_interface.cc Magics_interface.cc COPYONLY )
+ configure_file( Magics.i.in Magics/Magics.i )
# Copy python modules to build area
# configure_file ensures the copy is triggered if the file changes
@@ -10,11 +13,24 @@ if( HAVE_PYTHON )
configure_file( Magics/toolbox.py Magics/toolbox.py COPYONLY )
configure_file( Magics/metgram.py Magics/metgram.py COPYONLY )
-# ${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_BINARY_DIR}/lib
+ set( _magics_swig "_Magics${CMAKE_SHARED_LIBRARY_SUFFIX}" )
+ # Build the extension module for use in build tree with RPATH pointing to the build tree
+ add_custom_command( OUTPUT ${_magics_swig}
+ COMMAND ${PYTHON_EXECUTABLE} setup.py build_ext --inplace --rpath ${CMAKE_BINARY_DIR}/lib
+ DEPENDS Magics_interface.cc Magics.i.in numpy.i setup.py.in MagPlus )
+ add_custom_target(build_swig_wrapper ALL DEPENDS ${_magics_swig})
# Build the extension module for use in install tree with RPATH pointing to install tree
install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} setup.py build_ext --rpath ${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
+
+ # Library installation directory override
+ if( NOT INSTALL_LIB_DIR STREQUAL lib )
+ execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "from __future__ import print_function; import sys; print(sys.version[:3], end='')"
+ OUTPUT_VARIABLE PYVER )
+ set( __install_lib "--install-lib=${MAGICS_FULL_INSTALL_LIB_DIR}/python${PYVER}/site-packages" )
+ endif()
+
# Call distutils for installation
- install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} setup.py install --root \$ENV{DESTDIR}/ --prefix ${CMAKE_INSTALL_PREFIX} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
+ install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} setup.py install ${__install_lib} --root \$ENV{DESTDIR}/ --prefix ${CMAKE_INSTALL_PREFIX} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
endif()
diff --git a/python/Magics.i.in b/python/Magics.i.in
new file mode 100755
index 0000000..3663473
--- /dev/null
+++ b/python/Magics.i.in
@@ -0,0 +1,69 @@
+%module (docstring="This is a Python interface to Magics++") Magics
+
+%{
+#define SWIG_FILE_WITH_INIT
+/* Includes the header in the wrapper code */
+#include "Magics_interface.cc"
+%}
+
+%constant const char *__version__ ="@MAGICS_VERSION@";
+
+
+// This tells SWIG to treat char ** as a special case
+//
+// see http://www.swig.org/Doc1.3/Python.html#Python_nn59
+//
+%typemap(in) (const char **data, const int dim)
+{
+ /* Check if is a list */
+ if (PyList_Check($input))
+ {
+ int size = PyList_Size($input);
+ int i = 0;
+ $1 = (char **) malloc((size+1)*sizeof(char *));
+ $2 = size;
+ for (i = 0; i < size; i++) {
+ PyObject *o = PyList_GetItem($input,i);
+ if (PyString_Check(o))
+ $1[i] = PyString_AsString(PyList_GetItem($input,i));
+ else {
+ PyErr_SetString(PyExc_TypeError,"list must contain strings");
+ free($1);
+ return NULL;
+ }
+ }
+ $1[i] = 0;
+ }
+ else
+ {
+ PyErr_SetString(PyExc_TypeError,"not a list");
+ return NULL;
+ }
+}
+
+// This cleans up the char ** array we malloced before the function call
+%typemap(freearg) (const char **data, int dim)
+{
+ free((char *) $1);
+}
+
+
+/*
+ N U M E R I C A L A R R A Y S
+*/
+%include "numpy.i"
+%init %{
+ import_array();
+%}
+
+%apply(double* IN_ARRAY1, int DIM1) {(double *data, int dim)}
+%apply(int* IN_ARRAY1, int DIM1) {(int *data, int dim)}
+
+%apply(int* IN_ARRAY2, int DIM1, int DIM2) {(int *data, const int dim1, const int dim2)}
+%apply(int* IN_ARRAY2, int DIM1, int DIM2, int DIM3) {(int *data, const int dim1, const int dim2, const int dim3)}
+
+%apply(double* IN_ARRAY2, int DIM1, int DIM2) {(double *data, const int dim1, const int dim2)}
+%apply(double* IN_ARRAY2, int DIM1, int DIM2, int DIM3) {(double *data, const int dim1, const int dim2, const int dim3)}
+
+/* Parse the header file to generate wrappers */
+%include "Magics_interface.cc"
diff --git a/python/Magics.py.in b/python/Magics.py.in
deleted file mode 100644
index bfb3d6e..0000000
--- a/python/Magics.py.in
+++ /dev/null
@@ -1,499 +0,0 @@
-# (C) Copyright 2012-2016 ECMWF.
-#
-# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
-# granted to it by virtue of its status as an intergovernmental organisation nor
-# does it submit to any jurisdiction.
-#
-
-import ctypes
-import ctypes.util
-import sys
-
-import numpy as np
-from numpy.ctypeslib import ndpointer
-from functools import partial
-
-lib = ctypes.util.find_library("MagPlus")
-
-if lib is None:
- lib = "@CMAKE_BINARY_DIR@/lib/libMagPlus at CMAKE_SHARED_LIBRARY_SUFFIX@"
- if lib is None:
- lib = "@CMAKE_INSTALL_PREFIX@/@INSTALL_LIB_DIR@/libMagPlus at CMAKE_SHARED_LIBRARY_SUFFIX@"
-
-dll = ctypes.CDLL(lib)
-libc = ctypes.CDLL(ctypes.util.find_library("c"))
-
-
-class FILE(ctypes.Structure):
- pass
-
-
-FILE_p = ctypes.POINTER(FILE)
-
-######################## String conversions ##########################
-
-def _string_to_char(x):
- return x.encode()
-
-
-def _char_to_string(x):
- return x.decode()
-
-
-def _convert_strings(fn):
-
- convert = False
-
- for a in fn.argtypes:
- if a is c_char_p:
- convert = True
-
- if fn.restype is c_char_p:
- convert = True
-
- if not convert:
- return fn
-
- def wrapped(*args):
-
- new_args = []
- for a, t in zip(args, fn.argtypes):
- if t is c_char_p:
- a = string_to_char(a)
- new_args.append(a)
-
- r = fn(*new_args)
- if fn.restype is c_char_p:
- r = char_to_string(r)
- return r
-
- return wrapped
-
-if sys.version_info[0] > 2:
- convert_strings = _convert_strings
- char_to_string = _char_to_string
- string_to_char = _string_to_char
-else:
- convert_strings = lambda x: x
- char_to_string = lambda x: x
- string_to_char = lambda x: x
-
-
-
-
-
-####################################################################
-c_int = ctypes.c_int
-c_int_p = ctypes.POINTER(c_int)
-
-c_double = ctypes.c_double
-c_double_p = ctypes.POINTER(c_double)
-
-c_char = ctypes.c_char
-c_char_p = ctypes.c_char_p
-
-c_void_p = ctypes.c_void_p
-
-
-####################################################################
-def checked_error_in_last_paramater(fn):
-
- def wrapped(*args):
- err = c_int(0)
- err_p = ctypes.cast(ctypes.addressof(err), c_int_p)
- params = [a for a in args]
- params.append(err_p)
-
- result = fn(*params)
- if err.value:
- raise MagicsError(err)
- return result
-
- return wrapped
-
-
-def checked_return_code(fn):
-
- def wrapped(*args):
- err = fn(*args)
- if err:
- raise MagicsError(err)
-
- return wrapped
-
-
-####################################################################
-
-def return_type(fn, ctype):
-
- def wrapped(*args):
- result = ctype()
- result_p = ctypes.cast(ctypes.addressof(result), ctypes.POINTER(ctype))
- params = [a for a in args]
- params.append(result_p)
- fn(*params)
- return result.value
-
- return wrapped
-
-####################################################################
-
-init = dll.mag_open
-init.restype = None
-init.argtypes = None
-
-####################################################################
-
-finalize = dll.mag_close
-finalize.restype = None
-finalize.argtypes = None
-
-####################################################################
-
-coast = dll.mag_coast
-coast.restype = None
-coast.argtypes = None
-
-####################################################################
-
-grib = dll.mag_grib
-grib.restype = None
-grib.argtypes = None
-
-####################################################################
-
-cont = dll.mag_cont
-cont.restype = None
-cont.argtypes = None
-
-####################################################################
-
-legend = dll.mag_legend
-legend.restype = None
-legend.argtypes = None
-
-####################################################################
-
-odb = dll.mag_odb
-odb.restype = None
-odb.argtypes = None
-
-####################################################################
-
-obs = dll.mag_obs
-obs.restype = None
-obs.argtypes = None
-
-####################################################################
-
-raw = dll.mag_raw
-raw.restype = None
-raw.argtypes = None
-
-####################################################################
-
-netcdf = dll.mag_netcdf
-netcdf.restype = None
-netcdf.argtypes = None
-
-####################################################################
-
-image = dll.mag_image
-image.restype = None
-image.argtypes = None
-
-####################################################################
-
-plot = dll.mag_plot
-plot.restype = None
-plot.argtypes = None
-
-####################################################################
-
-text = dll.mag_text
-text.restype = None
-text.argtypes = None
-
-####################################################################
-
-wind = dll.mag_wind
-wind.restype = None
-wind.argtypes = None
-
-####################################################################
-
-line = dll.mag_line
-line.restype = None
-line.argtypes = None
-
-####################################################################
-
-symb = dll.mag_symb
-symb.restype = None
-symb.argtypes = None
-
-####################################################################
-
-boxplot = dll.mag_boxplot
-boxplot.restype = None
-boxplot.argtypes = None
-
-####################################################################
-
-taylor = dll.mag_taylor
-taylor.restype = None
-taylor.argtypes = None
-
-####################################################################
-
-tephi = dll.mag_tephi
-tephi.restype = None
-tephi.argtypes = None
-
-####################################################################
-
-graph = dll.mag_graph
-graph.restype = None
-graph.argtypes = None
-
-####################################################################
-
-axis = dll.mag_axis
-axis.restype = None
-axis.argtypes = None
-
-####################################################################
-
-geo = dll.mag_geo
-geo.restype = None
-geo.argtypes = None
-
-####################################################################
-
-mimport = dll.mag_import
-mimport.restype = None
-mimport.argtypes = None
-
-####################################################################
-
-info = dll.mag_info
-info.restype = None
-info.argtypes = None
-
-####################################################################
-
-minput = dll.mag_input
-minput.restype = None
-minput.argtypes = None
-
-####################################################################
-
-eps = dll.mag_eps
-eps.restype = None
-eps.argtypes = None
-
-####################################################################
-###
-### Please note: these two functions changed compared to the previous SWIG based Python interface
-###
-metgraph = dll.mag_metgraph
-metgraph.restype = None
-metgraph.argtypes = None
-
-epsinput = dll.mag_epsinput
-epsinput.restype = None
-epsinput.argtypes = None
-
-####################################################################
-###
-### Please note: this function was called mmetbufr to the previous SWIG based Python interface
-###
-metbufr = dll.mag_metbufr
-metbufr.restype = None
-metbufr.argtypes = None
-
-####################################################################
-
-epsgraph = dll.mag_epsgraph
-epsgraph.restype = None
-epsgraph.argtypes = None
-
-####################################################################
-
-epscloud = dll.mag_epscloud
-epscloud.restype = None
-epscloud.argtypes = None
-
-####################################################################
-
-epslight = dll.mag_epslight
-epslight.restype = None
-epslight.argtypes = None
-
-####################################################################
-
-epsplumes = dll.mag_epsplumes
-epsplumes.restype = None
-epsplumes.argtypes = None
-
-####################################################################
-
-epswind = dll.mag_epswind
-epswind.restype = None
-epswind.argtypes = None
-
-####################################################################
-
-epswave = dll.mag_epswave
-epswave.restype = None
-epswave.argtypes = None
-
-####################################################################
-
-epsbar = dll.mag_epsbar
-epsbar.restype = None
-epsbar.argtypes = None
-
-####################################################################
-
-epsshading = dll.mag_epsshading
-epsshading.restype = None
-epsshading.argtypes = None
-
-####################################################################
-
-wrepjson = dll.mag_wrepjson
-wrepjson.restype = None
-wrepjson.argtypes = None
-
-####################################################################
-
-geojson = dll.mag_geojson
-geojson.restype = None
-geojson.argtypes = None
-
-####################################################################
-
-mapgen = dll.mag_mapgen
-mapgen.restype = None
-mapgen.argtypes = None
-
-####################################################################
-
-mtable = dll.mag_table
-mtable.restype = None
-mtable.argtypes = None
-
-####################################################################
-
-seti = dll.mag_seti
-seti.restype = None
-seti.argtypes = (c_char_p, c_int)
-seti = convert_strings(seti)
-
-####################################################################
-
-def set1i(name,data):
-# array = np.empty((size,), dtype=np.float64)
-# array_p = array.ctypes.data_as(c_double_p)
-# _set1r(name, array_p, size)
- size = len(data)
- name = string_to_char(name)
- array_p = (ctypes.c_int * size)(*data)
- dll.mag_set1i(ctypes.c_char_p(name), array_p, size)
- return None
-
-####################################################################
-
-array_2d_int = ndpointer(dtype=np.int,ndim=2, flags='CONTIGUOUS')
-set2i = dll.mag_set2i
-set2i.restype = None
-set2i.argtypes = (c_char_p, array_2d_int, c_int, c_int)
-set2i = convert_strings(set2i)
-
-####################################################################
-
-setr = dll.mag_setr
-setr.restype = None
-setr.argtypes = (c_char_p, c_double)
-setr = convert_strings(setr)
-
-####################################################################
-
-def set1r(name,data):
- size = len(data)
- name = string_to_char(name)
- array_p = (ctypes.c_double * size)(*data)
- dll.mag_set1r(ctypes.c_char_p(name), array_p, size)
- return None
-
-####################################################################
-
-array_2d_double = ndpointer(dtype=np.double,ndim=2, flags='CONTIGUOUS')
-set2r = dll.mag_set2r
-set2r.restype = None
-set2r.argtypes = (c_char_p, array_2d_double, c_int, c_int)
-set2r = convert_strings(set2r)
-
-####################################################################
-
-setc = dll.mag_setc
-setc.restype = None
-setc.argtypes = (c_char_p, c_char_p)
-setc = convert_strings(setc)
-
-####################################################################
-def set1c(name,data):
- new_data=[]
- for s in data:
- new_data.append(string_to_char(s))
- name = string_to_char(name)
- data_p = (c_char_p * (len(new_data)))(*new_data)
- dll.mag_set1c(ctypes.c_char_p(name), data_p, len(new_data))
-
-####################################################################
-
-#enqi = dll.mag_enqi
-#enqi.restype = c_int
-#enqi.argtypes = (c_char_p,)
-
-####################################################################
-
-#enqr = dll.mag_enqr
-#enqr.restype = c_double
-#enqr.argtypes = (c_char_p,)
-
-####################################################################
-
-#enqc = dll.mag_enqc
-#enqc.restype = c_char_p
-#enqc.argtypes = (c_char_p,)
-
-####################################################################
-
-new_page = dll.mag_new
-new_page.restype = None
-new_page.argtypes = (c_char_p,)
-new_page = convert_strings(new_page)
-
-####################################################################
-
-reset = dll.mag_reset
-reset.restype = None
-reset.argtypes = (c_char_p,)
-reset = convert_strings(reset)
-
-####################################################################
-
-class MagicsError(Exception):
-
- def __init__(self, err):
- super(MagicsError, self).__init__("Magics Error - to be made clearer!!! (%s)" % err)
-
-####################################################################
-
-
-#if __name__ == "__main__":
-# print "..."
diff --git a/python/Magics/macro.py b/python/Magics/macro.py
index 1659e3a..bc72d88 100644
--- a/python/Magics/macro.py
+++ b/python/Magics/macro.py
@@ -1,15 +1,14 @@
# (C) Copyright 1996-2016 ECMWF.
-#
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
-import sys
import os
+import Magics
import numpy
-from . import Magics
class Context(object):
def __init__(self):
@@ -59,18 +58,18 @@ class Action(object):
self.action = action
self.args = args
if ( html == "") :
- self.html = verb
- else :
- self.html = "<a href=/wiki/display/MAGP/%s target='_blank'>%s</a>" % (html, verb)
+ self.html = verb
+ else :
+ self.html = "<a href=/wiki/display/MAGP/%s target='_blank'>%s</a>" % (html, verb)
def __repr__(self):
x = ""
- for key in list(self.args.keys()):
+ for key in self.args.keys():
x = x + " %s = '%s'\n" % (key, self.args[key])
return x
def inspect(self):
- print(self)
+ print self
def quote(self, v):
return "\"" + v + "\""
@@ -79,7 +78,7 @@ class Action(object):
sep=""
val="%s("%self.html
- for key in list(self.args.keys()):
+ for key in self.args.keys():
if isinstance(self.args[key], str):
if key == 'odb_data':
Magics.setc('odb_filename', self.args[key])
@@ -98,7 +97,7 @@ class Action(object):
vval += vsep + self.quote(v)
vsep = ", "
else :
- vval = self.quote(self.args[key][0]) + ", " + self.quote(self.args[key][1]) + ",...," + self.quote(self.args[key][-2]) + ", " + self.quote(self.args[key][-1])
+ vval = self.quote(self.args[key][0]) + ", " + self.quote(self.args[key][1]) + ",...," + self.quote(self.args[key][-2]) + ", " + self.quote(self.args[key][-1])
vval += ""
val+= '%s%s = [%s]'%(sep, key, vval)
elif isinstance(self.args[key][0], int):
@@ -109,7 +108,7 @@ class Action(object):
vval += vsep + ("%df"%v)
vsep = ", "
else :
- vval = ("%d"%self.args[key][0]) + ", " + ("%d"%self.args[key][1]) + ",...," + ("%d"%self.args[key][-2]) + ", " + ("%d"%self.args[key][-1])
+ vval = ("%d"%self.args[key][0]) + ", " + ("%d"%self.args[key][1]) + ",...," + ("%d"%self.args[key][-2]) + ", " + ("%d"%self.args[key][-1])
vval += ""
val+= '%s%s = %s'%(sep, key, vval)
elif isinstance(self.args[key][0], float):
@@ -120,8 +119,8 @@ class Action(object):
vval += vsep + ("%0.2f"%v)
vsep = ", "
else :
- vval = ("%0.2f"%self.args[key][0]) + ", " + ("%0.2f"%self.args[key][1]) + ",...," + ("%0.2f"%self.args[key][-2]) + ", " + ("%0.2f"%self.args[key][-1])
-
+ vval = ("%0.2f"%self.args[key][0]) + ", " + ("%0.2f"%self.args[key][1]) + ",...," + ("%0.2f"%self.args[key][-2]) + ", " + ("%0.2f"%self.args[key][-1])
+
vval += ""
val+= '%s%s = [%s]'%(sep, key, vval)
elif isinstance(self.args[key], numpy.ndarray) :
@@ -129,12 +128,12 @@ class Action(object):
dim = len(self.args[key].shape)
if isinstance(self.args[key][0], int):
if (dim == 2) :
- print("pset2i")
+ print "pset2i"
else :
- print("pset1i")
+ print "pset1i"
elif ( type == 'float64' or type == 'float32') :
if (dim == 2) :
- print("pset2r")
+ print "pset2r"
else :
vval = ""
vsep = ""
@@ -143,20 +142,20 @@ class Action(object):
vval += vsep + ("%0.2f"%v)
vsep = ", "
else :
- vval = ("%0.2f"%self.args[key][0]) + ", " + ("%0.2f"%self.args[key][1]) + ",...," + ("%0.2f"%self.args[key][-2]) + ", " + ("%0.2f"%self.args[key][-1])
+ vval = ("%0.2f"%self.args[key][0]) + ", " + ("%0.2f"%self.args[key][1]) + ",...," + ("%0.2f"%self.args[key][-2]) + ", " + ("%0.2f"%self.args[key][-1])
vval += ""
val+= '%s%s = [%s]'%(sep, key, vval)
else :
- print("type???->", key)
+ print "type???->", key
sep=",\n\t"
-
- print(file, val + ")\n")
+
+ print >>file, val + ")\n"
def tomv4(self, file):
sep="\t"
val="%s,\n"%self.verb.upper()
- for key in list(self.args.keys()):
+ for key in self.args.keys():
if isinstance(self.args[key], str):
if key == 'odb_data':
Magics.setc('odb_filename', self.args[key])
@@ -176,20 +175,20 @@ class Action(object):
vval += "]"
val+= '%s%s = %s'%(sep, key.upper(), vval)
elif isinstance(self.args[key][0], int):
- print("pset1i")
+ print "pset1i"
elif isinstance(self.args[key][0], float):
- print("pset1r")
+ print "pset1r"
elif isinstance(self.args[key], numpy.ndarray) :
type = self.args[key].dtype
dim = len(self.args[key].shape)
if isinstance(self.args[key][0], int):
if (dim == 2) :
- print("pset2i")
+ print "pset2i"
else :
- print("pset1i")
+ print "pset1i"
elif ( type == 'float64' or type == 'float32') :
if (dim == 2) :
- print("pset2r")
+ print "pset2r"
else :
vval = "["
vsep = ""
@@ -198,12 +197,12 @@ class Action(object):
vsep = ", "
vval += "]"
val+= '%s%s = %s'%(sep, key.upper(), vval)
-
+
else :
- print("type???->", key)
+ print "type???->", key
sep=",\n\t"
-
- print(file, val + "\n")
+
+ print >> file, val + "\n"
@@ -211,24 +210,24 @@ class Action(object):
def tofortran(self, f):
if self.action == Magics.new_page :
- print(f, '\tcall pnew("page")')
+ print >> f, '\tcall pnew("page")'
return
- for key in list(self.args.keys()):
+ for key in self.args.keys():
if isinstance(self.args[key], str):
if key == 'odb_data':
Magics.setc('odb_filename', self.args[key])
else:
- print (f, '\tcall psetc("%s", "%s")'%(key, self.args[key]))
+ print >> f, '\tcall psetc("%s", "%s")'%(key, self.args[key])
elif isinstance(self.args[key], int):
- print (f, '\tcall pseti("%s", %d)'%(key, self.args[key]))
+ print >>f, '\tcall pseti("%s", %d)'%(key, self.args[key])
elif isinstance(self.args[key], float):
- print (f, '\tcall psetr("%s", %0.2f)'%(key, self.args[key]))
+ print >> f, '\tcall psetr("%s", %0.2f)'%(key, self.args[key])
elif isinstance(self.args[key], list) :
if isinstance (self.args[key][0], str):
nb = 0
for v in self.args[key]:
nb = max(nb, len(v))
-
+
val = "(/"
sep = ""
newline = 70
@@ -239,9 +238,9 @@ class Action(object):
sep = ",&\n\t\t"
newline = newline + 70
val += "/)"
- print (f, '\tcall pset1c("%s", %s, %d)'%(key, val, len(self.args[key])))
+ print >>f, '\tcall pset1c("%s", %s, %d)'%(key, val, len(self.args[key]))
elif isinstance(self.args[key][0], int):
- print("pset1i")
+ print "pset1i"
elif isinstance(self.args[key][0], float):
val = "(/"
sep = ""
@@ -249,18 +248,18 @@ class Action(object):
val += sep + ("%0.2f" % v)
sep = ", "
val += "/)"
- print (f, '\tcall pset1r("%s", %s, %d)'%(key, val, len(self.args[key])))
+ print >>f, '\tcall pset1r("%s", %s, %d)'%(key, val, len(self.args[key]))
elif isinstance(self.args[key], numpy.ndarray) :
type = self.args[key].dtype
dim = len(self.args[key].shape)
if isinstance(self.args[key][0], int):
if (dim == 2) :
- print("pset2i")
+ print "pset2i"
else :
- print("pset1i")
+ print "pset1i"
elif ( type == 'float64' or type == 'float32') :
if (dim == 2) :
- print("pset2r")
+ print "pset2r"
else :
val = "(/"
sep = ""
@@ -268,49 +267,49 @@ class Action(object):
val += sep + ("%0.2f" % v)
sep = ", "
val += "/)"
- print (f, '\tcall pset1r("%s", %s, %d)'%(key, val, len(self.args[key])))
+ print >>f, '\tcall pset1r("%s", %s, %d)'%(key, val, len(self.args[key]))
elif isinstance(self.args[key][0], int):
- print("pset1r")
+ print "pset1r"
else :
- print("type???->", key)
+ print "type???->", key
if self.action != None and actions[self.verb] != "" and actions[self.verb] != "pinput":
- print (f, "\tcall %s\n"%actions[self.verb])
- for key in list(self.args.keys()):
- print (f, "\tcall preset('%s')"%key)
- print (f, "")
+ print >>f, "\tcall %s\n"%actions[self.verb]
+ for key in self.args.keys():
+ print >>f, "\tcall preset('%s')"%key
+ print >>f, ""
else:
- print (f, "")
+ print >>f, ""
def clean_object(self, obj):
- if sys.version_info[0] < 3:
+
if type(obj) in (int, float, str, bool, numpy.float64):
return obj
elif type(obj) == unicode:
return str(obj)
- elif type(obj) in (list, tuple, set, numpy.ndarray) and len(obj):
+ elif type(obj) in (list, tuple, set, numpy.ndarray):
if type(obj[0]) != unicode:
return obj
obj = list(obj)
for i,v in enumerate(obj):
obj[i] = self.clean_object(v)
elif type(obj) == dict:
- for i,v in list(obj.items()):
+ for i,v in obj.iteritems():
obj[i] = self.clean_object(v)
else:
- print("Invalid object in data, converting to string: ")
- print(type(obj))
- obj = str(obj)
- return obj
+ print "Invalid object in data, converting to string: "
+ print type(obj)
+ obj = str(obj)
+ return obj
def execute(self):
if ( self.action != Magics.odb) :
self.args = self.clean_object(self.args)
- for key in list(self.args.keys()):
+ for key in self.args.keys():
if isinstance(self.args[key], str):
if key == 'odb_data':
Magics.setc('odb_filename', self.args[key])
@@ -320,7 +319,7 @@ class Action(object):
Magics.seti(key, self.args[key])
elif isinstance(self.args[key], float):
Magics.setr(key, self.args[key])
- elif isinstance(self.args[key], list) and len(self.args[key]):
+ elif isinstance(self.args[key], list) :
if isinstance(self.args[key][0], str):
Magics.set1c(key, self.args[key])
elif isinstance(self.args[key][0], int):
@@ -329,21 +328,20 @@ class Action(object):
Magics.set1r(key, numpy.array(self.args[key]))
elif isinstance(self.args[key], numpy.ndarray) :
type = self.args[key].dtype
- data = self.args[key].copy()
- size = data.shape
- dim = len(size)
+ dim = len(self.args[key].shape)
if isinstance(self.args[key][0], int):
if (dim == 2) :
- Magics.set2i(key, data, size[0], size[1])
+ Magics.set2i(key, self.args[key].copy())
else :
- Magics.set1i(key, data, size[0])
+ Magics.set1i(key, self.args[key].copy())
elif ( type == 'float64' or type == 'float32') :
- if (dim == 2) :
- Magics.set2r(key, data, size[1], size[0])
+ if (dim == 2) :
+ Magics.set2r(key, self.args[key].copy())
else :
- Magics.set1r(key, data)
+ Magics.set1r(key, self.args[key].copy())
else :
- print("type???->", key)
+ print "type???->", key
+
else:
self.args[key].execute(key)
@@ -353,7 +351,7 @@ class Action(object):
Magics.setc("legend", "on")
self.action()
if self.action != Magics.obs and self.action != Magics.minput:
- for key in list(self.args.keys()):
+ for key in self.args.keys():
Magics.reset(key)
else:
self.action("page")
@@ -361,7 +359,7 @@ class Action(object):
def make_action(verb, action, html=""):
def f(_m = None,**kw):
args = {}
- if _m is not None:
+ if _m is not None:
args.update(_m)
args.update(kw)
return Action(verb, action, html, args)
@@ -426,8 +424,8 @@ mepsgraph = make_action("mepsgraph", Magics.epsgraph)
mepsplumes = make_action("mepsplumes", Magics.epsplumes)
mtephi = make_action("mtephi", Magics.tephi)
-mmetgraph = make_action("mmetgraph", Magics.metgraph)
-mmetbufr = make_action("mmetbufr", Magics.metbufr)
+mmetgraph = make_action("mmetgraph", Magics.mmetgraph)
+mmetbufr = make_action("mmetbufr", Magics.mmetbufr)
def examine(*args):
for n in args:
@@ -442,14 +440,14 @@ def _execute(o):
_execute(x)
else:
-
+
o.execute()
def _plot(*args):
Magics.init()
for n in args:
_execute(n)
-
+
#Collect the drivers!
Magics.finalize()
for f in context.tmp:
@@ -461,20 +459,20 @@ def _plot(*args):
def tofortran(file, *args):
f = open(file+".f90",'w')
- print(f, "\tprogram magics\n")
- print(f, "\tcall popen\n")
+ print >>f, "\tprogram magics\n"
+ print >>f, "\tcall popen\n"
for n in args:
n.tofortran(f)
- print(f, "\tcall pclose\n")
- print(f, "\tend")
+ print >>f, "\tcall pclose\n"
+ print >>f, "\tend"
def tohtml(file, *args):
f = open(file+".html",'w')
- print (f, "<html>")
+ print >>f, "<html>"
for n in args:
n.tohtml(f)
- print (f, "</html>")
+ print >>f, "</html>"
def tomv4(file, *args):
f = open(file+".mv4",'w')
@@ -490,22 +488,22 @@ class odb_filter(object):
self.args = args
def execute(self, key):
file = "data%d" % numpy.random.randint(1,1000)
- odb = "%s.odb" % file
+ odb = "%s.odb" % file
context.tmp.append(odb)
- cmd = "odbsql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -f newodb -o " + odb
- print(cmd)
+ cmd = "odb sql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -f newodb -o " + odb
+ print cmd
if (os.system(cmd)) :
- print("Error in filtering ODB data... Aborting")
+ print "Error in filtering ODB data... Aborting"
os.abort();
Magics.setc('odb_filename', odb)
def inspect(self):
- cmd = "odbsql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -o data.ascii"
+ cmd = "odb sql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -o data.ascii"
if (os.system(cmd)) :
- print("Error in filtering ODB data... Aborting")
+ print "Error in filtering ODB data... Aborting"
os.abort();
cmd = os.environ['ODB_REPORTER'] + " %s" % "data.ascii"
if (os.system(cmd)) :
- print("Error in viewing ODB data... Aborting")
+ print "Error in viewing ODB data... Aborting"
os.abort();
@@ -518,13 +516,15 @@ try:
LOCK = threading.Lock()
def plot(*args):
-
- with LOCK:
+
+ with LOCK:
f, tmp = tempfile.mkstemp(".png")
os.close(f)
-
+
base, ext = os.path.splitext(tmp)
+
+
img = output(output_formats=["png"],
output_name_first_page_number='off',
output_name=base)
@@ -533,7 +533,7 @@ try:
for i in args :
all.append(i)
_plot(all)
-
+
image = Image(tmp)
os.unlink(tmp)
return image
diff --git a/python/Magics/metgram.py b/python/Magics/metgram.py
index fd7bda3..ab87ef2 100644
--- a/python/Magics/metgram.py
+++ b/python/Magics/metgram.py
@@ -1,8 +1,8 @@
# (C) Copyright 1996-2016 ECMWF.
-#
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -66,8 +66,8 @@ definition.append({
definition.append({
"class": "vertical_axis",
"id" : "vaxis",
- "axis_line":"on",
- "axis_grid":"on",
+ "axis_line":"on",
+ "axis_grid":"on",
"axis_line_colour":"kelly_green" ,
"axis_tick_label_colour":"kelly_green",
"axis_label_font":"sansserif",
@@ -101,14 +101,14 @@ def page():
"horizontal_axis": { "use_id" : "haxis" },
"vertical_axis": { "use_id" : "vaxis" }
-
+
}
}
return page
class humidity(object):
-
+
def execute(self):
humi = {
"epsbufr":
@@ -132,7 +132,7 @@ class humidity(object):
return map
class msl(object):
-
+
def execute(self):
msl = {
"epsbufr":
@@ -154,7 +154,7 @@ class msl(object):
class cloud(object):
-
+
def execute(self):
cloud = {
"epsbufr":
@@ -178,7 +178,7 @@ class cloud(object):
return map
class precip(object):
-
+
def execute(self):
precip = {
"epsbufr":
@@ -198,7 +198,7 @@ class precip(object):
return map
class wind(object):
-
+
def execute(self):
wind = {
"epsbufr":
@@ -228,7 +228,7 @@ class wind(object):
return map
class tempe(object):
-
+
def execute(self):
t850 = {
"epsbufr":
@@ -238,7 +238,7 @@ class tempe(object):
"epsbufr_parameter_offset_factor": "-273.15",
"use_id":"station"
},
- "metgraph": {
+ "metgraph": {
"metgram_plot_style":"curve",
"metgram_curve_colour":"blue"
}
@@ -253,7 +253,7 @@ class tempe(object):
"epsbufr_parameter_offset_factor": "-273.15",
"use_id":"station"
},
- "metgraph": {
+ "metgraph": {
"metgram_plot_style":"curve",
"metgram_curve_colour":"red"
}
@@ -266,8 +266,11 @@ class tempe(object):
return map
+
+
+
class station(object):
- def __init__(self, args):
+ def __init__(self, args):
self.definition = args
self.definition["id"]= "station"
self.definition["class"]= "epsbufr"
@@ -275,8 +278,9 @@ class station(object):
magics["definition"].append(self.definition)
return page()
+
class ps(object):
- def __init__(self, args):
+ def __init__(self, args):
self.definition = args
self.definition["format"]= "ps"
def execute(self):
@@ -285,6 +289,8 @@ class ps(object):
magics["drivers"].append(self.definition)
return page()
+
+
@@ -300,8 +306,8 @@ def metgram(*args):
if (i == nb) :
haxis="haxis_last"
map["map"]["horizontal_axis"]["use_id"] = haxis
-
-
+
+
s = simplejson.dumps(magics, indent=4 * ' ')
f = tempfile.NamedTemporaryFile()
f.write(s)
@@ -311,9 +317,9 @@ def metgram(*args):
error = os.system(cmd)
if (error != 0):
- print("Error found - unix error: ", os.WEXITSTATUS(error) )
+ print "Error found"
f.close
-
+
cloud = cloud()
humidity = humidity()
@@ -321,3 +327,4 @@ precip = precip()
tempe = tempe()
msl = msl()
wind = wind()
+
diff --git a/python/Magics/toolbox.py b/python/Magics/toolbox.py
index 3f801b1..e1029f0 100644
--- a/python/Magics/toolbox.py
+++ b/python/Magics/toolbox.py
@@ -1,25 +1,24 @@
-# (C) Copyright 1996-2016 ECMWF.
-#
-# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
-# granted to it by virtue of its status as an intergovernmental organisation nor
-# does it submit to any jurisdiction.
-from . import macro
+import macro
def substitute(default, user):
out = default
if user != None:
for key in user:
out[key] = user[key]
+
+
+
return out
-def geoplot(data, contour=None, output=None, background=None, foreground=None, area=None, title=[]):
+
+def geoplot(data, contour=None, output=None, background=None, foreground=None, area=None, legend = None, title = []):
+
default = {
"area" : {},
+ "legend" : {},
"contour" : {},
"background" : { "map_coastline_sea_shade" : 'on',
"map_coastline_sea_shade_colour" : 'rgb(81,81,81)',
@@ -36,26 +35,23 @@ def geoplot(data, contour=None, output=None, background=None, foreground=None, a
}
- background = macro.mcoast( substitute(default["background"], background) )
- foreground = macro.mcoast( substitute(default["foreground"], foreground) )
- projection = macro.mmap( substitute(default["area"], area) )
- contour = macro.mcont( substitute(default["contour"], contour) )
+ background= macro.mcoast( substitute(default["background"], background) )
+ foreground= macro.mcoast( substitute(default["foreground"], foreground) )
- #Define the title
- title = macro.mtext(
- text_lines = title,
- text_font_size = 0.8,
- text_justification = "left"
- )
- if output == None :
- return macro.plot(projection, background, data, contour, foreground, title)
-
- return macro.plot(output, projection, background, data, contour, foreground, title)
+ projection = macro.mmap( substitute(default["area"], area)
+ )
+
+ contour = macro.mcont( substitute(default["contour"], contour) )
+
+ legend = macro.mlegend(substitute(default["legend"], legend))
+
+ return macro.plot(output, projection, background, data, contour, foreground, title, legend)
def xyplot(data, contour=None, output=None):
+
default = {
- "contour" : {}
+ "contour" : { }
}
#Setting the cartesian view
@@ -78,29 +74,29 @@ def xyplot(data, contour=None, output=None):
axis_grid_line_style = "dot")
- #Define the graph
- contour = macro.mcont( substitute(default["contour"], contour))
-
+ #Define the graph
+ contour = macro.mcont( substitute(default["contour"], contour)
+ )
#Define the title
title = macro.mtext(
text_font_size = 0.8,
text_justification = "left"
)
- if output == None:
- return macro.plot(output, projection, vertical, horizontal, data, contour, title)
return macro.plot(output, projection, vertical, horizontal, data, contour, title)
-def graph(x,y, title="", graph = None, colour = "ecmwf_blue") :
+def graph(x,y, title="", graph = None) :
default = {
- "graph" : { "graph_line_colour" : "ecmwf_blue",
+ "graph" : { "graph_line_colour" : "ecmwf_blue",
"graph_line_thickness" : 2,
- }
+ }
}
+
x[0] = x[0]*1.
y[0] = y[0]*1.
+
#Setting the cartesian view
projection = macro.mmap(subpage_map_projection = 'cartesian',
@@ -125,7 +121,7 @@ def graph(x,y, title="", graph = None, colour = "ecmwf_blue") :
input = macro.minput(input_x_values = x,
input_y_values = y)
- #Define the graph
+ #Define the graph
graph = macro.mgraph( substitute(default["graph"], graph)
)
#Define the title
@@ -385,14 +381,14 @@ def epsgraph(parameter, input, **args):
actions = []
-
+
projection = macro.mmap( substitute(defaults["eps"]["projection"], args.get("projection", None)) )
# define horizontal axis
- horizontal = macro.maxis(substitute(defaults["eps"]["horizontal_axis"], args.get("horizontal_axis", None)))
+ horizontal = macro.maxis(substitute(defaults["eps"]["horizontal_axis"], args.get("horizontal_axis", None)))
vertical = macro.maxis(substitute(defaults["eps"]["vertical_axis"], args.get("vertical_axis", None)))
-
-
+
+
data = macro.mwrepjson(
wrepjson_family = "eps",
wrepjson_keyword = "eps",
@@ -405,12 +401,13 @@ def epsgraph(parameter, input, **args):
)
graph = macro.mepsgraph(substitute(defaults["eps"]["epsgraph"], args.get("epsgraph", None)) )
+
+
actions.append(projection)
actions.append(vertical)
actions.append(horizontal)
-
-
+
if "climate" in args :
clim = macro.mwrepjson(
@@ -424,13 +421,15 @@ def epsgraph(parameter, input, **args):
wrepjson_missing_value = args.get("missing", 9999.),
wrepjson_parameter_information = "none",
wrepjson_position_information = "off"
+
)
shade = macro.mepsshading(substitute(defaults["eps"]["epsclim"], args.get("epsclim", None)) )
actions.append(clim)
actions.append(shade)
-
+
actions.append(data)
- actions.append(graph)
+ actions.append(graph)
+
text = macro.mtext(
text_colour = "navy",
@@ -441,10 +440,11 @@ def epsgraph(parameter, input, **args):
"<json_info key='product_info'/><json_info key='date'/>",
"<font size='0.5' colour='white'>.</font>",
"<json_info key='parameter_info'/>",]
+
)
actions.append(text)
-
+
if "output" in args != "" :
#Setting of the output file name
png = macro.output(output_formats = ['png'],
@@ -455,11 +455,14 @@ def epsgraph(parameter, input, **args):
subpage_y_position = 1.,
)
- return macro._plot(
- png,
+ return macro._plot(
+ png,
actions
- )
+ )
+ return macro.plot(
+ actions
+ )
def epsclimgram(**kw):
diff --git a/python/Magics_interface.cc b/python/Magics_interface.cc
new file mode 100755
index 0000000..0728bd5
--- /dev/null
+++ b/python/Magics_interface.cc
@@ -0,0 +1,255 @@
+/*
+ * (C) Copyright 1996-2016 ECMWF.
+ *
+ * This software is licensed under the terms of the Apache Licence Version 2.0
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
+ * granted to it by virtue of its status as an intergovernmental organisation nor
+ * does it submit to any jurisdiction.
+ */
+
+#include <magics_api.h>
+
+void init() {
+ mag_open ();
+}
+
+void finalize() {
+ mag_close();
+}
+
+void coast() {
+ mag_coast();
+}
+
+void grib() {
+ mag_grib();
+}
+
+void test() {
+ mag_test();
+}
+void legend() {
+ mag_legend();
+}
+
+void odb() {
+ mag_odb();
+}
+
+void netcdf() {
+ mag_netcdf();
+}
+
+void cont() {
+ mag_cont();
+}
+void minput() {
+ mag_input();
+}
+void mtable() {
+ mag_table();
+}
+void obs() {
+ mag_obs();
+}
+
+void raw() {
+ mag_raw();
+}
+
+void image() {
+ mag_image();
+}
+
+void plot() {
+ mag_plot();
+}
+
+void text() {
+ mag_text();
+}
+
+void wind() {
+ mag_wind();
+}
+void line() {
+ mag_line();
+}
+
+void symb() {
+ mag_symb();
+}
+
+void boxplot() {
+ mag_boxplot();
+}
+void taylor() {
+ mag_taylor();
+}
+void tephi() {
+ mag_tephi();
+}
+
+void mimport() {
+ mag_import();
+}
+void mmetgraph() {
+ mag_metgraph();
+}
+void mmetbufr() {
+ mag_metbufr();
+}
+void wrepjson() {
+ mag_wrepjson();
+}
+
+void geojson() {
+ mag_geojson();
+}
+
+void metgraph() {
+ mag_epsinput();
+}
+
+void epsinput() {
+ mag_epsinput();
+}
+void epsgraph() {
+ mag_epsgraph();
+}
+
+void epscloud() {
+ mag_epscloud();
+}
+void epslight() {
+ mag_epslight();
+}
+void epsplumes() {
+ mag_epsplumes();
+}
+
+void epswind() {
+ mag_epswind();
+}
+void epswave() {
+ mag_epswave();
+}
+
+void epsbar() {
+ mag_epsbar();
+}
+void epsshading() {
+ mag_epsshading();
+ }
+
+void mapgen() {
+ mag_mapgen();
+}
+
+void new_page(const char* page)
+{
+ mag_new(page);
+}
+
+void reset(const char* name)
+{
+ mag_reset(name);
+}
+
+void setc(const char* name, const char* value)
+{
+ mag_setc(name, value);
+}
+
+void setr(const char* name, const double value)
+{
+ // std::cout << "setr "<<name<<" = "<<value<< std::endl;
+ mag_setr(name, value);
+}
+
+void seti(const char* name, const int value)
+{
+ mag_seti(name, value);
+}
+
+double enqr(const char* name)
+{
+ double value = 0.;
+ mag_enqr (name, &value);
+ return value;
+}
+
+int enqi(const char* name)
+{
+ int value = 0;
+ mag_enqi ( name, &value);
+ return value;
+}
+
+char* enqc (const char* name)
+{
+ char *value = 0;
+ mag_enqc (name, value);
+ // std::cout << "nnn" << name<< " "<< value << std::endl;
+ return value;
+}
+
+void set1r(const char* name,double *data, const int dim)
+{
+ mag_set1r(name, data, dim);
+}
+
+void set2r(const char* name, double *data, const int dim1, const int dim2)
+{
+ mag_set2r(name, data, dim2, dim1);
+}
+
+void set3r(const char* name, double *data, const int dim1, const int dim2, const int dim3)
+{
+ mag_set3r(name, data, dim1, dim2, dim3);
+}
+
+void set1i(const char* name, int* data, const int dim)
+{
+ mag_set1i(name, data, dim);
+}
+
+void set2i(const char* name, int *data, const int dim1, const int dim2)
+{
+ mag_set2i(name, data, dim1, dim2);
+}
+
+void set3i(const char* name, int *data, const int dim1, const int dim2, const int dim3)
+{
+ mag_set3i(name, data, dim1, dim2, dim3);
+}
+
+void set1c(const char* name, const char** data, const int dim)
+{
+ mag_set1c(name, data, dim);
+}
+
+void pie() {
+ mag_pie();
+}
+
+void graph() {
+ mag_graph();
+}
+
+void axis() {
+ mag_axis();
+}
+
+void geo() {
+ mag_geo();
+}
+
+void eps() {
+ mag_eps();
+}
+
+void info() {
+ mag_info();
+}
diff --git a/python/numpy.i b/python/numpy.i
new file mode 100644
index 0000000..644e968
--- /dev/null
+++ b/python/numpy.i
@@ -0,0 +1,1634 @@
+/* -*- C -*- (not really, but good for syntax highlighting) */
+#ifdef SWIGPYTHON
+
+%{
+#ifndef SWIG_FILE_WITH_INIT
+# define NO_IMPORT_ARRAY
+#endif
+#include "stdio.h"
+#include <numpy/arrayobject.h>
+%}
+
+/**********************************************************************/
+
+%fragment("NumPy_Backward_Compatibility", "header")
+{
+/* Support older NumPy data type names
+*/
+%#if NDARRAY_VERSION < 0x01000000
+%#define NPY_BOOL PyArray_BOOL
+%#define NPY_BYTE PyArray_BYTE
+%#define NPY_UBYTE PyArray_UBYTE
+%#define NPY_SHORT PyArray_SHORT
+%#define NPY_USHORT PyArray_USHORT
+%#define NPY_INT PyArray_INT
+%#define NPY_UINT PyArray_UINT
+%#define NPY_LONG PyArray_LONG
+%#define NPY_ULONG PyArray_ULONG
+%#define NPY_LONGLONG PyArray_LONGLONG
+%#define NPY_ULONGLONG PyArray_ULONGLONG
+%#define NPY_FLOAT PyArray_FLOAT
+%#define NPY_DOUBLE PyArray_DOUBLE
+%#define NPY_LONGDOUBLE PyArray_LONGDOUBLE
+%#define NPY_CFLOAT PyArray_CFLOAT
+%#define NPY_CDOUBLE PyArray_CDOUBLE
+%#define NPY_CLONGDOUBLE PyArray_CLONGDOUBLE
+%#define NPY_OBJECT PyArray_OBJECT
+%#define NPY_STRING PyArray_STRING
+%#define NPY_UNICODE PyArray_UNICODE
+%#define NPY_VOID PyArray_VOID
+%#define NPY_NTYPES PyArray_NTYPES
+%#define NPY_NOTYPE PyArray_NOTYPE
+%#define NPY_CHAR PyArray_CHAR
+%#define NPY_USERDEF PyArray_USERDEF
+%#define npy_intp intp
+
+%#define NPY_MAX_BYTE MAX_BYTE
+%#define NPY_MIN_BYTE MIN_BYTE
+%#define NPY_MAX_UBYTE MAX_UBYTE
+%#define NPY_MAX_SHORT MAX_SHORT
+%#define NPY_MIN_SHORT MIN_SHORT
+%#define NPY_MAX_USHORT MAX_USHORT
+%#define NPY_MAX_INT MAX_INT
+%#define NPY_MIN_INT MIN_INT
+%#define NPY_MAX_UINT MAX_UINT
+%#define NPY_MAX_LONG MAX_LONG
+%#define NPY_MIN_LONG MIN_LONG
+%#define NPY_MAX_ULONG MAX_ULONG
+%#define NPY_MAX_LONGLONG MAX_LONGLONG
+%#define NPY_MIN_LONGLONG MIN_LONGLONG
+%#define NPY_MAX_ULONGLONG MAX_ULONGLONG
+%#define NPY_MAX_INTP MAX_INTP
+%#define NPY_MIN_INTP MIN_INTP
+
+%#define NPY_FARRAY FARRAY
+%#define NPY_F_CONTIGUOUS F_CONTIGUOUS
+%#endif
+}
+
+/**********************************************************************/
+
+/* The following code originally appeared in
+ * enthought/kiva/agg/src/numeric.i written by Eric Jones. It was
+ * translated from C++ to C by John Hunter. Bill Spotz has modified
+ * it to fix some minor bugs, upgrade from Numeric to numpy (all
+ * versions), add some comments and functionality, and convert from
+ * direct code insertion to SWIG fragments.
+ */
+
+%fragment("NumPy_Macros", "header")
+{
+/* Macros to extract array attributes.
+ */
+%#define is_array(a) ((a) && PyArray_Check((PyArrayObject *)a))
+%#define array_type(a) (int)(PyArray_TYPE(a))
+%#define array_numdims(a) (((PyArrayObject *)a)->nd)
+%#define array_dimensions(a) (((PyArrayObject *)a)->dimensions)
+%#define array_size(a,i) (((PyArrayObject *)a)->dimensions[i])
+%#define array_data(a) (((PyArrayObject *)a)->data)
+%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a))
+%#define array_is_native(a) (PyArray_ISNOTSWAPPED(a))
+%#define array_is_fortran(a) (PyArray_ISFORTRAN(a))
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Utilities", "header")
+{
+ /* Given a PyObject, return a string describing its type.
+ */
+ const char* pytype_string(PyObject* py_obj) {
+ if (py_obj == NULL ) return "C NULL value";
+ if (py_obj == Py_None ) return "Python None" ;
+ if (PyCallable_Check(py_obj)) return "callable" ;
+ if (PyString_Check( py_obj)) return "string" ;
+ if (PyInt_Check( py_obj)) return "int" ;
+ if (PyFloat_Check( py_obj)) return "float" ;
+ if (PyDict_Check( py_obj)) return "dict" ;
+ if (PyList_Check( py_obj)) return "list" ;
+ if (PyTuple_Check( py_obj)) return "tuple" ;
+ if (PyFile_Check( py_obj)) return "file" ;
+ if (PyModule_Check( py_obj)) return "module" ;
+ if (PyInstance_Check(py_obj)) return "instance" ;
+
+ return "unknown type";
+ }
+
+ /* Given a NumPy typecode, return a string describing the type.
+ */
+ const char* typecode_string(int typecode) {
+ static const char* type_names[25] = {"bool", "byte", "unsigned byte",
+ "short", "unsigned short", "int",
+ "unsigned int", "long", "unsigned long",
+ "long long", "unsigned long long",
+ "float", "double", "long double",
+ "complex float", "complex double",
+ "complex long double", "object",
+ "string", "unicode", "void", "ntypes",
+ "notype", "char", "unknown"};
+ return typecode < 24 ? type_names[typecode] : type_names[24];
+ }
+
+ /* Make sure input has correct numpy type. Allow character and byte
+ * to match. Also allow int and long to match. This is deprecated.
+ * You should use PyArray_EquivTypenums() instead.
+ */
+ int type_match(int actual_type, int desired_type) {
+ return PyArray_EquivTypenums(actual_type, desired_type);
+ }
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Object_to_Array", "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros",
+ fragment="NumPy_Utilities")
+{
+ /* Given a PyObject pointer, cast it to a PyArrayObject pointer if
+ * legal. If not, set the python error string appropriately and
+ * return NULL.
+ */
+ PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode)
+ {
+ PyArrayObject* ary = NULL;
+ if (is_array(input) && (typecode == NPY_NOTYPE ||
+ PyArray_EquivTypenums(array_type(input), typecode)))
+ {
+ ary = (PyArrayObject*) input;
+ }
+ else if is_array(input)
+ {
+ const char* desired_type = typecode_string(typecode);
+ const char* actual_type = typecode_string(array_type(input));
+ PyErr_Format(PyExc_TypeError,
+ "Array of type '%s' required. Array of type '%s' given",
+ desired_type, actual_type);
+ ary = NULL;
+ }
+ else
+ {
+ const char * desired_type = typecode_string(typecode);
+ const char * actual_type = pytype_string(input);
+ PyErr_Format(PyExc_TypeError,
+ "Array of type '%s' required. A '%s' was given",
+ desired_type, actual_type);
+ ary = NULL;
+ }
+ return ary;
+ }
+
+ /* Convert the given PyObject to a NumPy array with the given
+ * typecode. On success, return a valid PyArrayObject* with the
+ * correct type. On failure, the python error string will be set and
+ * the routine returns NULL.
+ */
+ PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
+ int* is_new_object)
+ {
+ PyArrayObject* ary = NULL;
+ PyObject* py_obj;
+ if (is_array(input) && (typecode == NPY_NOTYPE ||
+ PyArray_EquivTypenums(array_type(input),typecode)))
+ {
+ ary = (PyArrayObject*) input;
+ *is_new_object = 0;
+ }
+ else
+ {
+ py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_DEFAULT);
+ /* If NULL, PyArray_FromObject will have set python error value.*/
+ ary = (PyArrayObject*) py_obj;
+ *is_new_object = 1;
+ }
+ return ary;
+ }
+
+ /* Given a PyArrayObject, check to see if it is contiguous. If so,
+ * return the input pointer and flag it as not a new object. If it is
+ * not contiguous, create a new PyArrayObject using the original data,
+ * flag it as a new object and return the pointer.
+ */
+ PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object,
+ int min_dims, int max_dims)
+ {
+ PyArrayObject* result;
+ if (array_is_contiguous(ary))
+ {
+ result = ary;
+ *is_new_object = 0;
+ }
+ else
+ {
+ result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
+ array_type(ary),
+ min_dims,
+ max_dims);
+ *is_new_object = 1;
+ }
+ return result;
+ }
+
+ /* Given a PyArrayObject, check to see if it is Fortran-contiguous.
+ * If so, return the input pointer, but do not flag it as not a new
+ * object. If it is not Fortran-contiguous, create a new
+ * PyArrayObject using the original data, flag it as a new object
+ * and return the pointer.
+ */
+ PyArrayObject* make_fortran(PyArrayObject* ary, int* is_new_object,
+ int min_dims, int max_dims)
+ {
+ PyArrayObject* result;
+ if (array_is_fortran(ary))
+ {
+ result = ary;
+ *is_new_object = 0;
+ }
+ else
+ {
+ Py_INCREF(ary->descr);
+ result = (PyArrayObject*) PyArray_FromArray(ary, ary->descr, NPY_FORTRAN);
+ *is_new_object = 1;
+ }
+ return result;
+ }
+
+ /* Convert a given PyObject to a contiguous PyArrayObject of the
+ * specified type. If the input object is not a contiguous
+ * PyArrayObject, a new one will be created and the new object flag
+ * will be set.
+ */
+ PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ int is_new1 = 0;
+ int is_new2 = 0;
+ PyArrayObject* ary2;
+ PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
+ &is_new1);
+ if (ary1)
+ {
+ ary2 = make_contiguous(ary1, &is_new2, 0, 0);
+ if ( is_new1 && is_new2)
+ {
+ Py_DECREF(ary1);
+ }
+ ary1 = ary2;
+ }
+ *is_new_object = is_new1 || is_new2;
+ return ary1;
+ }
+
+ /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the
+ * specified type. If the input object is not a Fortran-ordered
+ * PyArrayObject, a new one will be created and the new object flag
+ * will be set.
+ */
+ PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ int is_new1 = 0;
+ int is_new2 = 0;
+ PyArrayObject* ary2;
+ PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
+ &is_new1);
+ if (ary1)
+ {
+ ary2 = make_fortran(ary1, &is_new2, 0, 0);
+ if (is_new1 && is_new2)
+ {
+ Py_DECREF(ary1);
+ }
+ ary1 = ary2;
+ }
+ *is_new_object = is_new1 || is_new2;
+ return ary1;
+ }
+
+} /* end fragment */
+
+
+/**********************************************************************/
+
+%fragment("NumPy_Array_Requirements", "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros")
+{
+ /* Test whether a python object is contiguous. If array is
+ * contiguous, return 1. Otherwise, set the python error string and
+ * return 0.
+ */
+ int require_contiguous(PyArrayObject* ary)
+ {
+ int contiguous = 1;
+ if (!array_is_contiguous(ary))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Array must be contiguous. A non-contiguous array was given");
+ contiguous = 0;
+ }
+ return contiguous;
+ }
+
+ /* Require that a numpy array is not byte-swapped. If the array is
+ * not byte-swapped, return 1. Otherwise, set the python error string
+ * and return 0.
+ */
+ int require_native(PyArrayObject* ary)
+ {
+ int native = 1;
+ if (!array_is_native(ary))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Array must have native byteorder. "
+ "A byte-swapped array was given");
+ native = 0;
+ }
+ return native;
+ }
+
+ /* Require the given PyArrayObject to have a specified number of
+ * dimensions. If the array has the specified number of dimensions,
+ * return 1. Otherwise, set the python error string and return 0.
+ */
+ int require_dimensions(PyArrayObject* ary, int exact_dimensions)
+ {
+ int success = 1;
+ if (array_numdims(ary) != exact_dimensions)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "Array must have %d dimensions. Given array has %d dimensions",
+ exact_dimensions, array_numdims(ary));
+ success = 0;
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to have one of a list of specified
+ * number of dimensions. If the array has one of the specified number
+ * of dimensions, return 1. Otherwise, set the python error string
+ * and return 0.
+ */
+ int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n)
+ {
+ int success = 0;
+ int i;
+ char dims_str[255] = "";
+ char s[255];
+ for (i = 0; i < n && !success; i++)
+ {
+ if (array_numdims(ary) == exact_dimensions[i])
+ {
+ success = 1;
+ }
+ }
+ if (!success)
+ {
+ for (i = 0; i < n-1; i++)
+ {
+ sprintf(s, "%d, ", exact_dimensions[i]);
+ strcat(dims_str,s);
+ }
+ sprintf(s, " or %d", exact_dimensions[n-1]);
+ strcat(dims_str,s);
+ PyErr_Format(PyExc_TypeError,
+ "Array must have %s dimensions. Given array has %d dimensions",
+ dims_str, array_numdims(ary));
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to have a specified shape. If the
+ * array has the specified shape, return 1. Otherwise, set the python
+ * error string and return 0.
+ */
+ int require_size(PyArrayObject* ary, npy_intp* size, int n)
+ {
+ int i;
+ int success = 1;
+ int len;
+ char desired_dims[255] = "[";
+ char s[255];
+ char actual_dims[255] = "[";
+ for(i=0; i < n;i++)
+ {
+ if (size[i] != -1 && size[i] != array_size(ary,i))
+ {
+ success = 0;
+ }
+ }
+ if (!success)
+ {
+ for (i = 0; i < n; i++)
+ {
+ if (size[i] == -1)
+ {
+ sprintf(s, "*,");
+ }
+ else
+ {
+ sprintf(s, "%ld,", (long int)size[i]);
+ }
+ strcat(desired_dims,s);
+ }
+ len = strlen(desired_dims);
+ desired_dims[len-1] = ']';
+ for (i = 0; i < n; i++)
+ {
+ sprintf(s, "%ld,", (long int)array_size(ary,i));
+ strcat(actual_dims,s);
+ }
+ len = strlen(actual_dims);
+ actual_dims[len-1] = ']';
+ PyErr_Format(PyExc_TypeError,
+ "Array must have shape of %s. Given array has shape of %s",
+ desired_dims, actual_dims);
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to to be FORTRAN ordered. If the
+ * the PyArrayObject is already FORTRAN ordered, do nothing. Else,
+ * set the FORTRAN ordering flag and recompute the strides.
+ */
+ int require_fortran(PyArrayObject* ary)
+ {
+ int success = 1;
+ int nd = array_numdims(ary);
+ int i;
+ if (array_is_fortran(ary)) return success;
+ /* Set the FORTRAN ordered flag */
+ ary->flags = NPY_FARRAY;
+ /* Recompute the strides */
+ ary->strides[0] = ary->strides[nd-1];
+ for (i=1; i < nd; ++i)
+ ary->strides[i] = ary->strides[i-1] * array_size(ary,i-1);
+ return success;
+ }
+}
+
+/* Combine all NumPy fragments into one for convenience */
+%fragment("NumPy_Fragments", "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros",
+ fragment="NumPy_Utilities",
+ fragment="NumPy_Object_to_Array",
+ fragment="NumPy_Array_Requirements") { }
+
+/* End John Hunter translation (with modifications by Bill Spotz)
+ */
+
+/* %numpy_typemaps() macro
+ *
+ * This macro defines a family of 41 typemaps that allow C arguments
+ * of the form
+ *
+ * (DATA_TYPE IN_ARRAY1[ANY])
+ * (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ * (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ *
+ * (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ * (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ * (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ *
+ * (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ * (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ * (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ *
+ * (DATA_TYPE INPLACE_ARRAY1[ANY])
+ * (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ * (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ *
+ * (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ * (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ * (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ *
+ * (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ * (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ * (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ *
+ * (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ * (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ * (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ *
+ * (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ *
+ * (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *
+ * (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ * (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ *
+ * (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ * (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ *
+ * (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ * (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ *
+ * where "DATA_TYPE" is any type supported by the NumPy module, and
+ * "DIM_TYPE" is any int-like type suitable for specifying dimensions.
+ * The difference between "ARRAY" typemaps and "FARRAY" typemaps is
+ * that the "FARRAY" typemaps expect FORTRAN ordering of
+ * multidimensional arrays. In python, the dimensions will not need
+ * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1"
+ * typemaps). The IN_ARRAYs can be a numpy array or any sequence that
+ * can be converted to a numpy array of the specified type. The
+ * INPLACE_ARRAYs must be numpy arrays of the appropriate type. The
+ * ARGOUT_ARRAYs will be returned as new numpy arrays of the
+ * appropriate type.
+ *
+ * These typemaps can be applied to existing functions using the
+ * %apply directive. For example:
+ *
+ * %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)};
+ * double prod(double* series, int length);
+ *
+ * %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2)
+ * {(int rows, int cols, double* matrix )};
+ * void floor(int rows, int cols, double* matrix, double f);
+ *
+ * %apply (double IN_ARRAY3[ANY][ANY][ANY])
+ * {(double tensor[2][2][2] )};
+ * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ * {(double low[2][2][2] )};
+ * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ * {(double upp[2][2][2] )};
+ * void luSplit(double tensor[2][2][2],
+ * double low[2][2][2],
+ * double upp[2][2][2] );
+ *
+ * or directly with
+ *
+ * double prod(double* IN_ARRAY1, int DIM1);
+ *
+ * void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f);
+ *
+ * void luSplit(double IN_ARRAY3[ANY][ANY][ANY],
+ * double ARGOUT_ARRAY3[ANY][ANY][ANY],
+ * double ARGOUT_ARRAY3[ANY][ANY][ANY]);
+ */
+
+%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)
+
+/************************/
+/* Input Array Typemaps */
+/************************/
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY1[ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY1[ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = { $1_dim0 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY1[ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = { -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = {-1};
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { $1_dim0, $1_dim1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* IN_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* IN_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/***************************/
+/* In-Place Array Typemaps */
+/***************************/
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY1[ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY1[ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[1] = { $1_dim0 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ (PyArrayObject* array=NULL, int i=1)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = 1;
+ for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ (PyArrayObject* array=NULL, int i=0)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = 1;
+ for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i);
+ $2 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[2] = { $1_dim0, $1_dim1 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+ !require_native(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+ || !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+ !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+ !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* INPLACE_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+ !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* INPLACE_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+ || !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+
+/*************************/
+/* Argout Array Typemaps */
+/*************************/
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ (PyObject * array = NULL)
+{
+ npy_intp dims[1] = { $1_dim0 };
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY1[ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ */
+%typemap(in,numinputs=1,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ (PyObject * array = NULL)
+{
+ npy_intp dims[1];
+ if (!PyInt_Check($input))
+ {
+ const char* typestring = pytype_string($input);
+ PyErr_Format(PyExc_TypeError,
+ "Int dimension expected. '%s' given.",
+ typestring);
+ SWIG_fail;
+ }
+ $2 = (DIM_TYPE) PyInt_AsLong($input);
+ dims[0] = (npy_intp) $2;
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+{
+ $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ */
+%typemap(in,numinputs=1,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ (PyObject * array = NULL)
+{
+ npy_intp dims[1];
+ if (!PyInt_Check($input))
+ {
+ const char* typestring = pytype_string($input);
+ PyErr_Format(PyExc_TypeError,
+ "Int dimension expected. '%s' given.",
+ typestring);
+ SWIG_fail;
+ }
+ $1 = (DIM_TYPE) PyInt_AsLong($input);
+ dims[0] = (npy_intp) $1;
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+ (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+{
+ $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ (PyObject * array = NULL)
+{
+ npy_intp dims[2] = { $1_dim0, $1_dim1 };
+ array = PyArray_SimpleNew(2, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ (PyObject * array = NULL)
+{
+ npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = PyArray_SimpleNew(3, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/*****************************/
+/* Argoutview Array Typemaps */
+/*****************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 )
+ (DATA_TYPE* data_temp , DIM_TYPE dim_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+{
+ npy_intp dims[1] = { *$2 };
+ PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ (DIM_TYPE dim_temp, DATA_TYPE* data_temp )
+{
+ $1 = &dim_temp;
+ $2 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+{
+ npy_intp dims[1] = { *$1 };
+ PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
+ (DATA_TYPE* data_temp , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+ npy_intp dims[2] = { *$2, *$3 };
+ PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+{
+ npy_intp dims[2] = { *$1, *$2 };
+ PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
+ (DATA_TYPE* data_temp , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+ npy_intp dims[2] = { *$2, *$3 };
+ PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject * array = (PyArrayObject*) obj;
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+{
+ npy_intp dims[2] = { *$1, *$2 };
+ PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+ PyArrayObject * array = (PyArrayObject*) obj;
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[3] = { *$2, *$3, *$4 };
+ PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+ DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp)
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+{
+ npy_intp dims[3] = { *$1, *$2, *$3 };
+ PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3));
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[3] = { *$2, *$3, *$4 };
+ PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject * array = (PyArrayObject*) obj;
+ if (!array || require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+ DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp)
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+{
+ npy_intp dims[3] = { *$1, *$2, *$3 };
+ PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3));
+ PyArrayObject * array = (PyArrayObject*) obj;
+ if (!array || require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+%enddef /* %numpy_typemaps() macro */
+/* *************************************************************** */
+
+/* Concrete instances of the %numpy_typemaps() macro: Each invocation
+ * below applies all of the typemaps above to the specified data type.
+ */
+%numpy_typemaps(signed char , NPY_BYTE , int)
+%numpy_typemaps(unsigned char , NPY_UBYTE , int)
+%numpy_typemaps(short , NPY_SHORT , int)
+%numpy_typemaps(unsigned short , NPY_USHORT , int)
+%numpy_typemaps(int , NPY_INT , int)
+%numpy_typemaps(unsigned int , NPY_UINT , int)
+%numpy_typemaps(long , NPY_LONG , int)
+%numpy_typemaps(unsigned long , NPY_ULONG , int)
+%numpy_typemaps(long long , NPY_LONGLONG , int)
+%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
+%numpy_typemaps(float , NPY_FLOAT , int)
+%numpy_typemaps(double , NPY_DOUBLE , int)
+
+/* ***************************************************************
+ * The follow macro expansion does not work, because C++ bool is 4
+ * bytes and NPY_BOOL is 1 byte
+ *
+ * %numpy_typemaps(bool, NPY_BOOL, int)
+ */
+
+/* ***************************************************************
+ * On my Mac, I get the following warning for this macro expansion:
+ * 'swig/python detected a memory leak of type 'long double *', no destructor found.'
+ *
+ * %numpy_typemaps(long double, NPY_LONGDOUBLE, int)
+ */
+
+/* ***************************************************************
+ * Swig complains about a syntax error for the following macro
+ * expansions:
+ *
+ * %numpy_typemaps(complex float, NPY_CFLOAT , int)
+ *
+ * %numpy_typemaps(complex double, NPY_CDOUBLE, int)
+ *
+ * %numpy_typemaps(complex long double, NPY_CLONGDOUBLE, int)
+ */
+
+#endif /* SWIGPYTHON */
diff --git a/python/setup.py.in b/python/setup.py.in
index 54e76c6..b83225c 100644
--- a/python/setup.py.in
+++ b/python/setup.py.in
@@ -4,6 +4,23 @@ from distutils.core import setup, Extension
import os
import sys
+import numpy
+# Obtain the numpy include directory. This logic works across numpy versions.
+try:
+ numpy_include = numpy.get_include()
+except AttributeError:
+ numpy_include = numpy.get_numpy_include()
+
+
+attdict = dict(
+ sources = ['Magics/Magics.i'],
+ swig_opts = ['-c++'],
+ include_dirs = ['.', '@CMAKE_CURRENT_SOURCE_DIR@/../src/common',numpy_include],
+ library_dirs = ["@CMAKE_BINARY_DIR@/lib"],
+ libraries = ["MagPlus","m"],
+ extra_objects = [],
+)
+
setup (name = 'Magics',
version = '@MAGICS_VERSION_STR@',
author = 'ECMWF',
@@ -11,5 +28,6 @@ setup (name = 'Magics',
description = """Magics Python interface""",
license = 'Apache License, Version 2.0',
url = 'https://software.ecmwf.int/Magics',
+ ext_modules = [Extension('Magics._Magics',**attdict)],
packages = ['Magics'],
)
diff --git a/python/test_for_ctypes/array.py b/python/test_for_ctypes/array.py
deleted file mode 100755
index 3a13b9b..0000000
--- a/python/test_for_ctypes/array.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-
-import Magics as Magics
-import numpy
-import math
-
-def f(x,y):
-# return ((math.sin((x-180.)/(2.*math.pi)))-(math.cos((y-90.)/(2.*math.pi))))
-# return ( (x-180.) + (y-90.)*3 )
- return (y-90.)
-
-
-Magics.init ()
-Magics.setc("output_format","ps")
-Magics.setc("output_name", "py_arrays")
-
-Magics.setr("INPUT_FIELD_INITIAL_LATITUDE",90.0)
-Magics.setr("INPUT_FIELD_INITIAL_LONGITUDE",0.0)
-Magics.setr("INPUT_FIELD_LATITUDE_STEP",-1.5)
-Magics.setr("INPUT_FIELD_LONGITUDE_STEP",1.5)
-
-NLON =360
-NLAT =180
-
-FIELD = numpy.fromfunction(f,(NLAT,NLON),dtype=numpy.float64)
-
-Magics.set2r("INPUT_FIELD",FIELD,360,180)
-Magics.setr("INPUT_FIELD_INITIAL_LONGITUDE",-180.)
-Magics.setr("INPUT_FIELD_INITIAL_LATITUDE",90.)
-Magics.setr("INPUT_FIELD_LONGITUDE_STEP",1.)
-Magics.setr("INPUT_FIELD_LATITUDE_STEP",-1.)
-
-
-Magics.setc("map_coastline_colour", "khaki")
-Magics.setc("map_grid_colour", "grey")
-
-Magics.setc("contour", "on")
-Magics.setc("contour_line_colour", "sky")
-Magics.setc("CONTOUR_HIGHLIGHT_COLOUR", "GREEN")
-Magics.setc("contour_label", "on")
-Magics.cont()
-
-Magics.text()
-Magics.coast()
-
-Magics.new_page ("SUPER_PAGE")
-
-Magics.setr("SUBPAGE_LOWER_LEFT_LATITUDE", 30.0)
-Magics.setr("SUBPAGE_LOWER_LEFT_LONGITUDE", -30.0)
-Magics.setr("SUBPAGE_UPPER_RIGHT_LATITUDE", 65.0)
-Magics.setr("SUBPAGE_UPPER_RIGHT_LONGITUDE", 70.0)
-
-Magics.cont()
-Magics.text()
-Magics.coast()
-
-Magics.finalize()
diff --git a/python/test_for_ctypes/test_ctypes.py b/python/test_for_ctypes/test_ctypes.py
deleted file mode 100644
index 9c6561a..0000000
--- a/python/test_for_ctypes/test_ctypes.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import Magics as ma
-
-ma.init()
-ma.setr("subpage_lower_left_latitude", 40.)
-ma.setr("subpage_lower_left_longitude", -20.)
-ma.setr("subpage_upper_right_latitude", 65.)
-ma.setr("subpage_upper_right_longitude", 10.)
-
-ma.setc("grib_input_file_name", "../test/data.grib")
-ma.grib()
-
-ma.cont()
-
-ma.coast()
-
-#print ma.enqr("subpage_lower_left_latitude")
-
-ma.new_page("page")
-
-ma.reset("subpage_lower_left_latitude")
-ma.reset("subpage_lower_left_longitude")
-
-ma.coast()
-#print ma.enqr("subpage_lower_left_latitude")
-
-ma.info()
-
-ma.finalize()
diff --git a/python/test_for_ctypes/test_ctypes_graph.py b/python/test_for_ctypes/test_ctypes_graph.py
deleted file mode 100644
index 6b6aafc..0000000
--- a/python/test_for_ctypes/test_ctypes_graph.py
+++ /dev/null
@@ -1,58 +0,0 @@
-import Magics as ma
-import numpy as np
-
-ma.init()
-
-ma.setr("subpage_y_position", 2.)
-ma.setc("subpage_map_projection",'cartesian')
-ma.setc("subpage_x_axis_type",'date')
-ma.setc("subpage_y_axis_type",'regular')
-ma.setc("subpage_x_date_min","2012-03-01 12:00:00")
-ma.setc("subpage_x_date_max","2012-03-03 12:00:00")
-ma.setr("subpage_x_min",25.)
-ma.setr("subpage_x_max",75.)
-ma.setr("subpage_y_min",25.)
-ma.setr("subpage_y_max",75.)
-
-ma.setc("axis_orientation","vertical")
-ma.setc("axis_type","regular")
-ma.setc("axis_tick_label_colour",'navy')
-ma.setc("axis_grid","on")
-ma.setc("axis_grid_colour","grey")
-ma.setc("axis_grid_line_style","dot")
-ma.setr("axis_tick_label_height",0.4)
-ma.seti("axis_grid_thickness",1)
-ma.axis()
-
-ma.setc("axis_orientation","horizontal")
-ma.setc("axis_type","date")
-ma.setc("axis_grid","on")
-ma.setr("axis_days_label_height",0.40)
-ma.setr("axis_months_label_height",0.40)
-ma.setr("axis_years_label_height",0.50)
-ma.setc("axis_grid_colour","grey")
-ma.seti("axis_grid_thickness",1)
-ma.setc("axis_grid_line_style","dot")
-ma.axis()
-
-
-x = ["2012-03-02 00:00:00","2012-03-02 12:00:00","2012-03-03 00:00:00"]
-y = np.array([50.,30.,40.])
-ma.set1c("input_date_x_values",x,3)
-ma.set1r("input_y_values",y,3)
-ma.minput()
-
-ma.setc("graph_type","bar")
-ma.setc("graph_bar_colour",'evergreen')
-ma.setr("graph_bar_width",7200.)
-
-ma.graph()
-
-ma.set1c("text_lines",["Simple Bar","Second line"],2)
-ma.setc("text_justification","left")
-ma.setr("text_font_size",1.)
-ma.setc("text_colour", "charcoal")
-
-ma.text();
-
-ma.finalize()
diff --git a/src/basic/Layer.cc b/src/basic/Layer.cc
index d6748f9..8aed461 100644
--- a/src/basic/Layer.cc
+++ b/src/basic/Layer.cc
@@ -140,7 +140,7 @@ void Layer:: execute(const BaseDriver& ) const
void Layer::collectText(vector<TextVisitor*>& texts, LegendVisitor* legend)
{
-
+ if ( !visibility_) return;
if ( !object_)
return;
@@ -232,8 +232,8 @@ void SingleLayer::magnify(const BaseDriver& driver, float ,float )
void SingleLayer::execute(const BaseDriver& driver) const
{
-// if ( !parentLayer_->visibility() )
-// return;
+ if ( !parentLayer_->visibility() )
+ return;
ASSERT(objects_);
objects_->redisplay(driver);
@@ -257,8 +257,8 @@ void SingleLayer::update(const Layout& parent)
void SingleLayer::getReady() const
{
-// if ( !parentLayer_->visibility() )
-// return;
+ if ( !parentLayer_->visibility() )
+ return;
if ( parentLayer_->parent()->state() == geometry_changed) {
ASSERT(objects_);
objects_->clear();
@@ -314,7 +314,7 @@ void StepLayer::redisplay(const BaseDriver& driver) const
void StepLayer::execute(int i, const BaseDriver& driver, const Layout& layout) const
{
- if ( i < steps_.size() ) {
+ if ( visibility_ && i < steps_.size() ) {
steps_[i]->update(layout);
steps_[i]->execute(driver);
}
@@ -322,8 +322,8 @@ void StepLayer::execute(int i, const BaseDriver& driver, const Layout& layout) c
void StepLayer::getReady(int i) const
{
-
- steps_[i]->getReady();
+ if ( visibility_ )
+ steps_[i]->getReady();
}
void StepLayer::newLayer(const BaseDriver& driver)
@@ -395,8 +395,8 @@ void StaticLayer::redisplay(const BaseDriver& driver) const
void StaticLayer::execute(const BaseDriver& driver) const
{
-
- redisplay(driver);
+ if ( visibility_ )
+ redisplay(driver);
}
void StaticLayer::getReady() const
@@ -407,6 +407,7 @@ void StaticLayer::collect(MetaDataCollector& infos)
{
if(object_)
object_->visit(infos);
+ //layer_->transformation().collect(infos);
}
void StaticLayer::collect(ValuesCollector& values)
@@ -543,34 +544,6 @@ void TextLayer::execute(const BaseDriver& driver) const
layout->redisplay(driver);
}
-void LegendLayer::getReady() const {}
-void LegendLayer::execute(const BaseDriver&) const {}
-void LegendLayer::execute(int, const BaseDriver&) const {}
-
-void LegendLayer::getInfo(int, const BaseDriver& driver) const
-{
- // We assume hat "TextLayer::getInfo" has been called before!
- Layout parent;
- parent.parent(parent_);
- parent.name("Clone for legend");
-
- parent.width(parent_->layoutPtr()->width());
- parent.height(parent_->layoutPtr()->height());
- parent.x(parent_->layoutPtr()->x());
- parent.y(parent_->layoutPtr()->y());
-
- LegendVisitor* legend = this->parent()->legend();
-
- if ( legend ) {
- Layout* layout = new Layout();
- layout->parent(parent_);
- legend->finish(*layout);
- parent.push_back(layout);
- }
- parent.redisplay(driver);
-
-}
-
void TextLayer::getInfo(int i, const BaseDriver& driver) const
@@ -591,7 +564,16 @@ void TextLayer::getInfo(int i, const BaseDriver& driver) const
layout->parent(parent_);
parent_->finishText(*layout);
parent->push_back(layout);
-
+
+ LegendVisitor* legend = this->parent()->legend();
+
+ if ( legend ) {
+ Layout* layout = new Layout();
+ layout->parent(parent_);
+
+ legend->finish(*layout);
+ parent->push_back(layout);
+ }
parent->redisplay(driver);
delete parent;
}
@@ -623,19 +605,6 @@ SceneLayer::~SceneLayer()
}
}
-void SceneLayer::text(TextVisitor* text)
-{
- textVisitors_.push_back(text);
- textHandler_.icon(*text);
-}
-
-void SceneLayer::legend(LegendVisitor* legend)
-{
- legend_ = legend;
- if ( legend )
- legendHandler_.icon(*legend);
-}
-
bool SceneLayer::buildTree(const Layout& parent, unsigned int frame, const BaseDriver& out) const
{
if (frame >= numberOfSteps() ) return false;
@@ -669,17 +638,14 @@ void SceneLayer::redisplay(const BaseDriver& driver) const
unsigned int nb = frames.size();
switch ( mode_) {
case paper: {
-
+ textHandler_.name("Titles");
textHandler_.parent(const_cast<SceneLayer*>(this));
- legendHandler_.name("Legend");
- legendHandler_.parent(const_cast<SceneLayer*>(this));
if ( nb == 0) {
for ( int i = 0; i < numberOfSteps(); i++ )
{
getReady(i);
execute(i, driver);
textHandler_.getInfo(i, driver);
- legendHandler_.getInfo(i, driver);
}
}
else {
@@ -693,23 +659,20 @@ void SceneLayer::redisplay(const BaseDriver& driver) const
getReady(i);
execute(i, driver);
textHandler_.getInfo(i, driver);
- legendHandler_.getInfo(i, driver);
}
}
}
break;
case basic:
-
+ textHandler_.name("Titles");
textHandler_.parent(const_cast<SceneLayer*>(this));
- legendHandler_.name("Legend");
- legendHandler_.parent(const_cast<SceneLayer*>(this));
+
if ( nb == 0) {
for ( int i = 0; i < numberOfSteps(); i++ )
{
getReady(i);
execute(i, driver);
textHandler_.getInfo(i, driver);
- legendHandler_.getInfo(i, driver);
}
}
else {
@@ -718,16 +681,14 @@ void SceneLayer::redisplay(const BaseDriver& driver) const
getReady(f);
execute(f, driver);
textHandler_.getInfo(f, driver);
- legendHandler_.getInfo(f, driver);
}
}
break;
case interactif:
visit(driver);
-
+ textHandler_.name("Titles");
textHandler_.parent(const_cast<SceneLayer*>(this));
const_cast<SceneLayer*>(this)->add(&textHandler_);
- const_cast<SceneLayer*>(this)->add(&legendHandler_);
// here we add the Layer dedicated to the text ! ...
driver.redisplay(*this);
break;
@@ -1051,9 +1012,13 @@ void MetviewIcon::visit(Layer& layer)
{
if ( !iconClass_.empty() && !iconName_.empty() )
{
- layer.icon(*this);
+ layer.icon(iconName_,iconClass_,iconId_);
}
+ //if ( !iconClass_.empty() && !iconName_.empty() )
+ // layer.icon(iconName_, iconClass_);
+
+ layer.id(iconId_);
}
void MetviewIcon::visit(MetaDataCollector& collector)
diff --git a/src/basic/Layer.h b/src/basic/Layer.h
index fd5141a..a06e525 100644
--- a/src/basic/Layer.h
+++ b/src/basic/Layer.h
@@ -110,17 +110,7 @@ public:
vector<MetviewIcon >::const_iterator iconsEnd() { return icons_.end(); }
void icon(const string& iconname, const string& iconclass,const string& iconid)
{ icons_.push_back(MetviewIcon(iconname, iconclass,iconid)); }
- void icon(const MetviewIcon& icon)
- { MetviewIcon add;
- add.icon(icon);
- icons_.push_back(add);
- visibility_ = icon.visibility();
- transparency_ = icon.transparency();
-//F20161116 zindex_ = icon.zindex();
- id_ = icon.id();
- name_ = icon.name();
- }
-
+
//void setInfo(const string& name, const string& value) { information_[name]=value; }
//virtual const map<string, string>& getInfos(bool =false) const { return information_; }
@@ -282,17 +272,7 @@ public:
void collectText(vector<TextVisitor*>&, LegendVisitor*); // update the text informations!
};
-class LegendLayer : public StepLayer
-{
-public:
- LegendLayer() {}
- ~LegendLayer() {}
- void getReady() const;
- void execute(const BaseDriver&) const;
- void execute(int, const BaseDriver&) const;
- void getInfo(int, const BaseDriver&) const;
-
-};
+
/*
* A SceneLayer is attach to a SceneNode...
* It contains the list of layers needed to perform a plot.
@@ -314,9 +294,8 @@ public:
Layer* findLayer(Layer*,int) const;
- void legend(LegendVisitor* legend);
- void text(TextVisitor* text);
-
+ void legend(LegendVisitor* legend) { legend_ = legend; }
+ void text(TextVisitor* text) { textVisitors_.push_back(text); }
void getReady(int) const;
@@ -356,7 +335,6 @@ protected:
mutable std::set<LayoutVisitor*> visitors_;
mutable vector<TextVisitor*> textVisitors_;
mutable TextLayer textHandler_;
- mutable LegendLayer legendHandler_;
mutable LegendVisitor* legend_;
MagicsMode mode_;
diff --git a/src/basic/MagicsEvent.h b/src/basic/MagicsEvent.h
index dd664df..d8951dd 100644
--- a/src/basic/MagicsEvent.h
+++ b/src/basic/MagicsEvent.h
@@ -260,22 +260,13 @@ struct MetviewIcon
{
public:
MetviewIcon(const string& name = "", const string& cname = "", const string& id="unknown") :
- iconName_(name), iconClass_(cname), iconId_(id), visibilityLayer_(true), zindexLayer_(-1), transparencyLayer_(0) {};
+ iconName_(name), iconClass_(cname), iconId_(id) {};
void icon(const string& name, const string& cname, const string& id="unknown") {
iconName_ = name;
iconClass_ = cname;
iconId_ = id;
}
-
- void layerInfo(bool visibility, int zindex, int transparency, const string& id, const string& name) {
- visibilityLayer_ = visibility;
- zindexLayer_ = zindex;
- transparencyLayer_ = transparency;
- idLayer_ = id;
- nameLayer_ = name;
- }
-
virtual void visit(Layer& layer);
virtual void visit(MetaDataCollector& collector);
@@ -288,34 +279,18 @@ public:
iconName_ = other.iconName_;
iconClass_ = other.iconClass_;
iconId_ = other.iconId_;
- visibilityLayer_ = other.visibilityLayer_;
- zindexLayer_ = other.zindexLayer_;
- transparencyLayer_ = other.transparencyLayer_;
- idLayer_ = other.idLayer_;
- nameLayer_ = other.nameLayer_;
-
}
- string iconName() const { return iconName_; }
- string iconClass() const { return iconClass_; }
- string iconId() const { return iconId_; }
- int zindex() const { return zindexLayer_; }
- int visibility() const { return visibilityLayer_; }
- int transparency() const { return transparencyLayer_; }
- const string& id() const { return idLayer_; }
- const string& name() const { return nameLayer_; }
+ string iconName() const {return iconName_;}
+ string iconClass() const {return iconClass_;}
+ string iconId() const {return iconId_;}
+
+
protected:
string iconName_;
string iconClass_;
string iconId_;
- bool visibilityLayer_;
- int zindexLayer_;
- int transparencyLayer_;
- string idLayer_;
- string nameLayer_;
-
map<string, string> information_;
-
};
} // namespace magics
diff --git a/src/basic/ViewNode.cc b/src/basic/ViewNode.cc
index 55fd947..958a07a 100644
--- a/src/basic/ViewNode.cc
+++ b/src/basic/ViewNode.cc
@@ -179,16 +179,14 @@ void ViewNode::prepareLayout(SceneLayer& tree)
// Then the axis!
leftAxis_ = new LeftAxisVisitor(*drawing_);
- leftAxis_->width(vaxis);
- leftAxis_->frameIt();
-
+ leftAxis_->width(vaxis);
+ leftAxis_->frameIt();
components_.push_back(leftAxis_);
helper.attachLeft(leftAxis_);
rightAxis_ = new RightAxisVisitor(*drawing_);
- rightAxis_->width(vaxis);
- rightAxis_->frameIt();
-
+ rightAxis_->width(vaxis);
+ rightAxis_->frameIt();
helper.attachRight(rightAxis_);
components_.push_back(rightAxis_);
@@ -199,25 +197,23 @@ void ViewNode::prepareLayout(SceneLayer& tree)
topAxis_ = new TopAxisVisitor(*drawing_);
topAxis_->height(topaxis);
topAxis_->frameIt();
-
helper.attachTop(topAxis_);
components_.push_back(topAxis_);
helper.add(topAxis_);
+
bottomAxis_ = new BottomAxisVisitor(*drawing_);
- bottomAxis_->height(bottomaxis);
- bottomAxis_->frameIt();
-
+ bottomAxis_->height(bottomaxis);
+ bottomAxis_->frameIt();
components_.push_back(bottomAxis_);
helper.attachBottom(bottomAxis_);
helper.add(leftAxis_);
helper.add(rightAxis_);
-
- tree.legend(legend_);
- if ( needLegend_ )
+ if ( legend_)
{
+ tree.legend(legend_);
if ( !legend_->positional() ) {
if ( legend_->top() ) {
legend_->height(5);
@@ -233,14 +229,11 @@ void ViewNode::prepareLayout(SceneLayer& tree)
}
helper.add(legend_);
}
+ ((BasicSceneObject*)legend_)->parent((BasicSceneObject*)this);
+ legend_->getReady();
+
+ components_.push_back(legend_);
}
- if (legend_)
- {
- ((BasicSceneObject*)legend_)->parent((BasicSceneObject*)this);
- legend_->getReady();
- components_.push_back(legend_);
- }
-
for (vector<TextVisitor*>::iterator text = texts_.begin(); text != texts_.end(); ++text)
{
@@ -292,27 +285,27 @@ void ViewNode::visit(SceneLayer& tree)
tree.rules(rules_);
// Here we checkeing for the legend!
- needLegend_ = false;
+ bool legend = false;
for ( vector<BasicSceneObject*>::iterator item = items_.begin(); item != items_.end(); ++item) {
- needLegend_ = (*item)->needLegend();
- if ( needLegend_ ) break;
+ legend = (*item)->needLegend();
+ if ( legend ) break;
}
-
+ if ( !legend ) {
+ legend_ = 0;
+ }
//Here we have the steps!
prepareLayout(tree);
-
if ( items_.empty() )
{
push_back(new EmptySceneObject() );
}
- if ( needLegend_ ) {
- for ( vector<BasicSceneObject*>::iterator item = items_.begin(); item != items_.end(); ++item) {
- (*item)->getReady(*legend_);
- }
+ if (legend_) {
+ for ( vector<BasicSceneObject*>::iterator item = items_.begin(); item != items_.end(); ++item) {
+ (*item)->getReady(*legend_);
+ }
}
-
for ( vector<BasicSceneObject*>::iterator item = items_.begin(); item != items_.end(); ++item) {
(*item)->visit(tree, components_);
}
@@ -564,7 +557,7 @@ void FortranViewNode::getReady()
if ( predefined_ ) {
StyleLibrary library("projections");
const map<string, string>& area = library.get(predefined_name_);
- cout << "Setting predefined area --> " << predefined_name_ << endl;
+
viewTransformation_ = MagTranslator<string, Transformation>()(area.find("subpage_map_projection")->second);
viewTransformation_->set(area);
viewTransformation_->init();
diff --git a/src/basic/ViewNode.h b/src/basic/ViewNode.h
index feabe50..3a6a9e7 100644
--- a/src/basic/ViewNode.h
+++ b/src/basic/ViewNode.h
@@ -89,7 +89,7 @@ protected:
string animation_;
DrawingVisitor* drawing_;
- FrameVisitor* frameHelper_;
+ FrameVisitor* frameHelper_;
TopAxisVisitor* topAxis_;
BottomAxisVisitor* bottomAxis_;
LeftAxisVisitor* leftAxis_;
@@ -99,8 +99,7 @@ protected:
AnimationRules* rules_;
- bool needLegend_;
- LegendVisitor* legend_;
+ LegendVisitor* legend_;
vector<TextVisitor*> texts_;
vector<LayoutVisitor*> components_;
diff --git a/src/basic/VisualAction.cc b/src/basic/VisualAction.cc
index 208f7f1..94e277b 100644
--- a/src/basic/VisualAction.cc
+++ b/src/basic/VisualAction.cc
@@ -248,8 +248,9 @@ void VisualAnimation::prepare()
return;
layer_ = new StepLayer();
- layer_->id(loop_->id());
-
+ layer_->name(loop_->name());
+ layer_->id(loop_->name());
+ layer_->uniqueId(loop_->iconId());
loop_->visit(*layer_);
for ( vector<Visdef* >::iterator visdef = this->visdefs_.begin(); visdef != this->visdefs_.end(); ++visdef)
@@ -323,8 +324,6 @@ void VisualAction::visit(SceneLayer& layer, vector<LayoutVisitor*>& visitors)
{
layer_ = new StaticLayer(this);
-
- layer_->icon(*data_);
if ( data_ )
data_->visit(*layer_);
layer.add(layer_);
diff --git a/src/boost/README.update_boost b/src/boost/README.update_boost
new file mode 100644
index 0000000..51fde66
--- /dev/null
+++ b/src/boost/README.update_boost
@@ -0,0 +1,23 @@
+### PREP
+
+cd /hugetmp/boost-trunk/boost
+svn update
+
+
+### UPDATE
+
+ma
+cd src/boost/
+p4 edit ...
+rm -rf geometry/ range/
+cp -R /hugetmp/boost\-trunk/boost/geometry .
+cp -R /hugetmp/boost\-trunk/boost/range .
+p4 revert -a ...
+
+rm -rf src/boost/*/*/.svn src/boost/*/*/*/.svn src/boost/*/*/*/*/.svn
+rm -rf src/boost/*/*/*/*/*/.svn src/boost/*/*/*/*/*/*/.svn
+
+p4 add */* */*/* */*/*/* */*/*/*/* */*/*/*/*/* */*/*/*/*/*/*
+
+>>> BE AWARE OF src/boost/geometry/views/reversible_view.hpp
+
diff --git a/src/boost/geometry/algorithms/append.hpp b/src/boost/geometry/algorithms/append.hpp
new file mode 100644
index 0000000..72b2bba
--- /dev/null
+++ b/src/boost/geometry/algorithms/append.hpp
@@ -0,0 +1,233 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
+
+#include <boost/range.hpp>
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace append
+{
+
+template <typename Geometry, typename Point>
+struct append_no_action
+{
+ static inline void apply(Geometry& , Point const& ,
+ int = 0, int = 0)
+ {
+ }
+};
+
+template <typename Geometry, typename Point>
+struct append_point
+{
+ static inline void apply(Geometry& geometry, Point const& point,
+ int = 0, int = 0)
+ {
+ typename geometry::point_type<Geometry>::type copy;
+ geometry::detail::conversion::convert_point_to_point(point, copy);
+ traits::push_back<Geometry>::apply(geometry, copy);
+ }
+};
+
+
+template <typename Geometry, typename Range>
+struct append_range
+{
+ typedef typename boost::range_value<Range>::type point_type;
+
+ static inline void apply(Geometry& geometry, Range const& range,
+ int = 0, int = 0)
+ {
+ for (typename boost::range_iterator<Range const>::type
+ it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ append_point<Geometry, point_type>::apply(geometry, *it);
+ }
+ }
+};
+
+
+template <typename Polygon, typename Point>
+struct point_to_polygon
+{
+ typedef typename ring_type<Polygon>::type ring_type;
+
+ static inline void apply(Polygon& polygon, Point const& point,
+ int ring_index, int = 0)
+ {
+ if (ring_index == -1)
+ {
+ append_point<ring_type, Point>::apply(
+ exterior_ring(polygon), point);
+ }
+ else if (ring_index < int(num_interior_rings(polygon)))
+ {
+ append_point<ring_type, Point>::apply(
+ interior_rings(polygon)[ring_index], point);
+ }
+ }
+};
+
+
+template <typename Polygon, typename Range>
+struct range_to_polygon
+{
+ typedef typename ring_type<Polygon>::type ring_type;
+
+ static inline void apply(Polygon& polygon, Range const& range,
+ int ring_index, int )
+ {
+ if (ring_index == -1)
+ {
+ append_range<ring_type, Range>::apply(
+ exterior_ring(polygon), range);
+ }
+ else if (ring_index < int(num_interior_rings(polygon)))
+ {
+ append_range<ring_type, Range>::apply(
+ interior_rings(polygon)[ring_index], range);
+ }
+ }
+};
+
+
+}} // namespace detail::append
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+namespace splitted_dispatch
+{
+
+template <typename Tag, typename Geometry, typename Point>
+struct append_point
+ : detail::append::append_no_action<Geometry, Point>
+{};
+
+template <typename Geometry, typename Point>
+struct append_point<linestring_tag, Geometry, Point>
+ : detail::append::append_point<Geometry, Point>
+{};
+
+template <typename Geometry, typename Point>
+struct append_point<ring_tag, Geometry, Point>
+ : detail::append::append_point<Geometry, Point>
+{};
+
+
+template <typename Polygon, typename Point>
+struct append_point<polygon_tag, Polygon, Point>
+ : detail::append::point_to_polygon<Polygon, Point>
+{};
+
+
+template <typename Tag, typename Geometry, typename Range>
+struct append_range
+ : detail::append::append_no_action<Geometry, Range>
+{};
+
+template <typename Geometry, typename Range>
+struct append_range<linestring_tag, Geometry, Range>
+ : detail::append::append_range<Geometry, Range>
+{};
+
+template <typename Geometry, typename Range>
+struct append_range<ring_tag, Geometry, Range>
+ : detail::append::append_range<Geometry, Range>
+{};
+
+
+template <typename Polygon, typename Range>
+struct append_range<polygon_tag, Polygon, Range>
+ : detail::append::range_to_polygon<Polygon, Range>
+{};
+
+}
+
+
+// Default: append a range (or linestring or ring or whatever) to any geometry
+template
+<
+ typename Geometry, typename RangeOrPoint,
+ typename TagRangeOrPoint = typename tag<RangeOrPoint>::type
+>
+struct append
+ : splitted_dispatch::append_range<typename tag<Geometry>::type, Geometry, RangeOrPoint>
+{};
+
+// Specialization for point to append a point to any geometry
+template <typename Geometry, typename RangeOrPoint>
+struct append<Geometry, RangeOrPoint, point_tag>
+ : splitted_dispatch::append_point<typename tag<Geometry>::type, Geometry, RangeOrPoint>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Appends one or more points to a linestring, ring, polygon, multi-geometry
+\ingroup append
+\tparam Geometry \tparam_geometry
+\tparam RangeOrPoint Either a range or a point, fullfilling Boost.Range concept or Boost.Geometry Point Concept
+\param geometry \param_geometry
+\param range_or_point The point or range to add
+\param ring_index The index of the ring in case of a polygon:
+ exterior ring (-1, the default) or interior ring index
+\param multi_index Reserved for multi polygons or multi linestrings
+
+\qbk{[include reference/algorithms/append.qbk]}
+}
+ */
+template <typename Geometry, typename RangeOrPoint>
+inline void append(Geometry& geometry, RangeOrPoint const& range_or_point,
+ int ring_index = -1, int multi_index = 0)
+{
+ concept::check<Geometry>();
+
+ dispatch::append
+ <
+ Geometry,
+ RangeOrPoint
+ >::apply(geometry, range_or_point, ring_index, multi_index);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_APPEND_HPP
diff --git a/src/boost/geometry/algorithms/area.hpp b/src/boost/geometry/algorithms/area.hpp
new file mode 100644
index 0000000..8193200
--- /dev/null
+++ b/src/boost/geometry/algorithms/area.hpp
@@ -0,0 +1,295 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
+
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/detail/calculate_null.hpp>
+#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
+// #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
+
+#include <boost/geometry/strategies/area.hpp>
+#include <boost/geometry/strategies/default_area_result.hpp>
+
+#include <boost/geometry/strategies/concepts/area_concept.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/order_as_direction.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace area
+{
+
+template<typename Box, typename Strategy>
+struct box_area
+{
+ typedef typename coordinate_type<Box>::type return_type;
+
+ static inline return_type apply(Box const& box, Strategy const&)
+ {
+ // Currently only works for 2D Cartesian boxes
+ assert_dimension<Box, 2>();
+
+ return_type const dx = get<max_corner, 0>(box)
+ - get<min_corner, 0>(box);
+ return_type const dy = get<max_corner, 1>(box)
+ - get<min_corner, 1>(box);
+
+ return dx * dy;
+ }
+};
+
+
+template
+<
+ typename Ring,
+ iterate_direction Direction,
+ closure_selector Closure,
+ typename Strategy
+>
+struct ring_area
+{
+ BOOST_CONCEPT_ASSERT( (geometry::concept::AreaStrategy<Strategy>) );
+
+ typedef typename Strategy::return_type type;
+
+ static inline type apply(Ring const& ring, Strategy const& strategy)
+ {
+ assert_dimension<Ring, 2>();
+
+ // Ignore warning (because using static method sometimes) on strategy
+ boost::ignore_unused_variable_warning(strategy);
+
+ // An open ring has at least three points,
+ // A closed ring has at least four points,
+ // if not, there is no (zero) area
+ if (int(boost::size(ring))
+ < core_detail::closure::minimum_ring_size<Closure>::value)
+ {
+ return type();
+ }
+
+ typedef typename reversible_view<Ring const, Direction>::type rview_type;
+ typedef typename closeable_view
+ <
+ rview_type const, Closure
+ >::type view_type;
+ typedef typename boost::range_iterator<view_type const>::type iterator_type;
+
+ rview_type rview(ring);
+ view_type view(rview);
+ typename Strategy::state_type state;
+ iterator_type it = boost::begin(view);
+ iterator_type end = boost::end(view);
+
+ for (iterator_type previous = it++;
+ it != end;
+ ++previous, ++it)
+ {
+ strategy.apply(*previous, *it, state);
+ }
+
+ return strategy.result(state);
+ }
+};
+
+
+}} // namespace detail::area
+
+
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry,
+ typename Strategy = typename strategy::area::services::default_strategy
+ <
+ typename cs_tag
+ <
+ typename point_type<Geometry>::type
+ >::type,
+ typename point_type<Geometry>::type
+ >::type,
+ typename Tag = typename tag<Geometry>::type
+>
+struct area
+ : detail::calculate_null
+ <
+ typename Strategy::return_type,
+ Geometry,
+ Strategy
+ > {};
+
+
+template
+<
+ typename Geometry,
+ typename Strategy
+>
+struct area<Geometry, Strategy, box_tag>
+ : detail::area::box_area<Geometry, Strategy>
+{};
+
+
+template
+<
+ typename Ring,
+ typename Strategy
+>
+struct area<Ring, Strategy, ring_tag>
+ : detail::area::ring_area
+ <
+ Ring,
+ order_as_direction<geometry::point_order<Ring>::value>::value,
+ geometry::closure<Ring>::value,
+ Strategy
+ >
+{};
+
+
+template
+<
+ typename Polygon,
+ typename Strategy
+>
+struct area<Polygon, Strategy, polygon_tag>
+ : detail::calculate_polygon_sum
+ <
+ typename Strategy::return_type,
+ Polygon,
+ Strategy,
+ detail::area::ring_area
+ <
+ typename ring_type<Polygon const>::type,
+ order_as_direction<geometry::point_order<Polygon>::value>::value,
+ geometry::closure<Polygon>::value,
+ Strategy
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+\brief \brief_calc{area}
+\ingroup area
+\details \details_calc{area}. \details_default_strategy
+
+The area algorithm calculates the surface area of all geometries having a surface, namely
+box, polygon, ring, multipolygon. The units are the square of the units used for the points
+defining the surface. If subject geometry is defined in meters, then area is calculated
+in square meters.
+
+The area calculation can be done in all three common coordinate systems, Cartesian, Spherical
+and Geographic as well.
+
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{area}
+
+\qbk{[include reference/algorithms/area.qbk]}
+\qbk{[heading Examples]}
+\qbk{[area] [area_output]}
+*/
+template <typename Geometry>
+inline typename default_area_result<Geometry>::type area(Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename strategy::area::services::default_strategy
+ <
+ typename cs_tag<point_type>::type,
+ point_type
+ >::type strategy_type;
+
+ // detail::throw_on_empty_input(geometry);
+
+ return dispatch::area
+ <
+ Geometry
+ >::apply(geometry, strategy_type());
+}
+
+/*!
+\brief \brief_calc{area} \brief_strategy
+\ingroup area
+\details \details_calc{area} \brief_strategy. \details_strategy_reasons
+\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{Area}
+\param geometry \param_geometry
+\param strategy \param_strategy{area}
+\return \return_calc{area}
+
+\qbk{distinguish,with strategy}
+
+\qbk{
+[include reference/algorithms/area.qbk]
+
+[heading Example]
+[area_with_strategy]
+[area_with_strategy_output]
+
+[heading Available Strategies]
+\* [link geometry.reference.strategies.strategy_area_surveyor Surveyor (cartesian)]
+\* [link geometry.reference.strategies.strategy_area_huiller Huiller (spherical)]
+}
+ */
+template <typename Geometry, typename Strategy>
+inline typename Strategy::return_type area(
+ Geometry const& geometry, Strategy const& strategy)
+{
+ concept::check<Geometry const>();
+
+ // detail::throw_on_empty_input(geometry);
+
+ return dispatch::area
+ <
+ Geometry,
+ Strategy
+ >::apply(geometry, strategy);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
diff --git a/src/boost/geometry/algorithms/assign.hpp b/src/boost/geometry/algorithms/assign.hpp
new file mode 100644
index 0000000..8c153c8
--- /dev/null
+++ b/src/boost/geometry/algorithms/assign.hpp
@@ -0,0 +1,171 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
+
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/numeric/conversion/bounds.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
+#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
+#include <boost/geometry/algorithms/detail/assign_values.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/append.hpp>
+#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/for_each_coordinate.hpp>
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Assign a range of points to a linestring, ring or polygon
+\note The point-type of the range might be different from the point-type of the geometry
+\ingroup assign
+\tparam Geometry \tparam_geometry
+\tparam Range \tparam_range_point
+\param geometry \param_geometry
+\param range \param_range_point
+
+\qbk{
+[heading Notes]
+[note Assign automatically clears the geometry before assigning (use append if you don't want that)]
+[heading Example]
+[assign_points] [assign_points_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.append append]
+}
+ */
+template <typename Geometry, typename Range>
+inline void assign_points(Geometry& geometry, Range const& range)
+{
+ concept::check<Geometry>();
+
+ clear(geometry);
+ geometry::append(geometry, range, -1, 0);
+}
+
+
+/*!
+\brief assign to a box inverse infinite
+\details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
+min corner is very large, the max corner is very small. This is a convenient starting point to
+collect the minimum bounding box of a geometry.
+\ingroup assign
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+
+\qbk{
+[heading Example]
+[assign_inverse] [assign_inverse_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.make.make_inverse make_inverse]
+}
+ */
+template <typename Geometry>
+inline void assign_inverse(Geometry& geometry)
+{
+ concept::check<Geometry>();
+
+ dispatch::assign_inverse
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(geometry);
+}
+
+/*!
+\brief assign zero values to a box, point
+\ingroup assign
+\details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+
+ */
+template <typename Geometry>
+inline void assign_zero(Geometry& geometry)
+{
+ concept::check<Geometry>();
+
+ dispatch::assign_zero
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(geometry);
+}
+
+/*!
+\brief Assigns one geometry to another geometry
+\details The assign algorithm assigns one geometry, e.g. a BOX, to another geometry, e.g. a RING. This only
+if it is possible and applicable.
+\ingroup assign
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry (target)
+\param geometry2 \param_geometry (source)
+
+\qbk{
+[heading Example]
+[assign] [assign_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.convert convert]
+}
+ */
+template <typename Geometry1, typename Geometry2>
+inline void assign(Geometry1& geometry1, Geometry2 const& geometry2)
+{
+ concept::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>();
+
+ bool const same_point_order =
+ point_order<Geometry1>::value == point_order<Geometry2>::value;
+ bool const same_closure =
+ closure<Geometry1>::value == closure<Geometry2>::value;
+
+ BOOST_MPL_ASSERT_MSG
+ (
+ same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER
+ , (types<Geometry1, Geometry2>)
+ );
+ BOOST_MPL_ASSERT_MSG
+ (
+ same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE
+ , (types<Geometry1, Geometry2>)
+ );
+
+ dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1);
+}
+
+
+}} // namespace boost::geometry
+
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
diff --git a/src/boost/geometry/algorithms/buffer.hpp b/src/boost/geometry/algorithms/buffer.hpp
new file mode 100644
index 0000000..e22e36a
--- /dev/null
+++ b/src/boost/geometry/algorithms/buffer.hpp
@@ -0,0 +1,167 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+
+#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t D, std::size_t N>
+struct box_loop
+{
+ typedef typename coordinate_type<BoxOut>::type coordinate_type;
+
+ static inline void apply(BoxIn const& box_in, T const& distance, BoxOut& box_out)
+ {
+ coordinate_type d = distance;
+ set<C, D>(box_out, get<C, D>(box_in) + d);
+ box_loop<BoxIn, BoxOut, T, C, D + 1, N>::apply(box_in, distance, box_out);
+ }
+};
+
+template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t N>
+struct box_loop<BoxIn, BoxOut, T, C, N, N>
+{
+ static inline void apply(BoxIn const&, T const&, BoxOut&) {}
+};
+
+// Extends a box with the same amount in all directions
+template<typename BoxIn, typename BoxOut, typename T>
+inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out)
+{
+ assert_dimension_equal<BoxIn, BoxOut>();
+
+ static const std::size_t N = dimension<BoxIn>::value;
+
+ box_loop<BoxIn, BoxOut, T, min_corner, 0, N>::apply(box_in, -distance, box_out);
+ box_loop<BoxIn, BoxOut, T, max_corner, 0, N>::apply(box_in, distance, box_out);
+}
+
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename TagIn, typename TagOut, typename Input, typename T, typename Output>
+struct buffer {};
+
+
+template <typename BoxIn, typename T, typename BoxOut>
+struct buffer<box_tag, box_tag, BoxIn, T, BoxOut>
+{
+ static inline void apply(BoxIn const& box_in, T const& distance,
+ T const& , BoxIn& box_out)
+ {
+ detail::buffer::buffer_box(box_in, distance, box_out);
+ }
+};
+
+// Many things to do. Point is easy, other geometries require self intersections
+// For point, note that it should output as a polygon (like the rest). Buffers
+// of a set of geometries are often lateron combined using a "dissolve" operation.
+// Two points close to each other get a combined kidney shaped buffer then.
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_calc{buffer}
+\ingroup buffer
+\details \details_calc{buffer, \det_buffer}.
+\tparam Input \tparam_geometry
+\tparam Output \tparam_geometry
+\tparam Distance \tparam_numeric
+\param geometry_in \param_geometry
+\param geometry_out \param_geometry
+\param distance The distance to be used for the buffer
+\param chord_length (optional) The length of the chord's in the generated arcs around points or bends
+\note Currently only implemented for box, the trivial case, but still useful
+
+\qbk{[include reference/algorithms/buffer.qbk]}
+ */
+template <typename Input, typename Output, typename Distance>
+inline void buffer(Input const& geometry_in, Output& geometry_out,
+ Distance const& distance, Distance const& chord_length = -1)
+{
+ concept::check<Input const>();
+ concept::check<Output>();
+
+ dispatch::buffer
+ <
+ typename tag<Input>::type,
+ typename tag<Output>::type,
+ Input,
+ Distance,
+ Output
+ >::apply(geometry_in, distance, chord_length, geometry_out);
+}
+
+/*!
+\brief \brief_calc{buffer}
+\ingroup buffer
+\details \details_calc{return_buffer, \det_buffer}. \details_return{buffer}.
+\tparam Input \tparam_geometry
+\tparam Output \tparam_geometry
+\tparam Distance \tparam_numeric
+\param geometry \param_geometry
+\param distance The distance to be used for the buffer
+\param chord_length (optional) The length of the chord's in the generated arcs around points or bends
+\return \return_calc{buffer}
+ */
+template <typename Output, typename Input, typename T>
+Output return_buffer(Input const& geometry, T const& distance, T const& chord_length = -1)
+{
+ concept::check<Input const>();
+ concept::check<Output>();
+
+ Output geometry_out;
+
+ dispatch::buffer
+ <
+ typename tag<Input>::type,
+ typename tag<Output>::type,
+ Input,
+ T,
+ Output
+ >::apply(geometry, distance, chord_length, geometry_out);
+
+ return geometry_out;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP
diff --git a/src/boost/geometry/algorithms/centroid.hpp b/src/boost/geometry/algorithms/centroid.hpp
new file mode 100644
index 0000000..69ad9fe
--- /dev/null
+++ b/src/boost/geometry/algorithms/centroid.hpp
@@ -0,0 +1,470 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_CENTROID_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_CENTROID_HPP
+
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/exception.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/centroid.hpp>
+#include <boost/geometry/strategies/concepts/centroid_concept.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+
+#include <boost/geometry/util/for_each_coordinate.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
+
+/*!
+\brief Centroid Exception
+\ingroup centroid
+\details The centroid_exception is thrown if the free centroid function is called with
+ geometries for which the centroid cannot be calculated. For example: a linestring
+ without points, a polygon without points, an empty multi-geometry.
+\qbk{
+[heading See also]
+\* [link geometry.reference.algorithms.centroid the centroid function]
+}
+
+ */
+class centroid_exception : public geometry::exception
+{
+public:
+
+ inline centroid_exception() {}
+
+ virtual char const* what() const throw()
+ {
+ return "Boost.Geometry Centroid calculation exception";
+ }
+};
+
+#endif
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace centroid
+{
+
+template<typename Point, typename PointCentroid, typename Strategy>
+struct centroid_point
+{
+ static inline void apply(Point const& point, PointCentroid& centroid,
+ Strategy const&)
+ {
+ geometry::convert(point, centroid);
+ }
+};
+
+template
+<
+ typename Box,
+ typename Point,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct centroid_box_calculator
+{
+ typedef typename select_coordinate_type
+ <
+ Box, Point
+ >::type coordinate_type;
+ static inline void apply(Box const& box, Point& centroid)
+ {
+ coordinate_type const c1 = get<min_corner, Dimension>(box);
+ coordinate_type const c2 = get<max_corner, Dimension>(box);
+ coordinate_type m = c1 + c2;
+ m /= 2.0;
+
+ set<Dimension>(centroid, m);
+
+ centroid_box_calculator
+ <
+ Box, Point,
+ Dimension + 1, DimensionCount
+ >::apply(box, centroid);
+ }
+};
+
+
+template<typename Box, typename Point, std::size_t DimensionCount>
+struct centroid_box_calculator<Box, Point, DimensionCount, DimensionCount>
+{
+ static inline void apply(Box const& , Point& )
+ {
+ }
+};
+
+
+template<typename Box, typename Point, typename Strategy>
+struct centroid_box
+{
+ static inline void apply(Box const& box, Point& centroid,
+ Strategy const&)
+ {
+ centroid_box_calculator
+ <
+ Box, Point,
+ 0, dimension<Box>::type::value
+ >::apply(box, centroid);
+ }
+};
+
+
+// There is one thing where centroid is different from e.g. within.
+// If the ring has only one point, it might make sense that
+// that point is the centroid.
+template<typename Point, typename Range>
+inline bool range_ok(Range const& range, Point& centroid)
+{
+ std::size_t const n = boost::size(range);
+ if (n > 1)
+ {
+ return true;
+ }
+ else if (n <= 0)
+ {
+#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
+ throw centroid_exception();
+#endif
+ return false;
+ }
+ else // if (n == 1)
+ {
+ // Take over the first point in a "coordinate neutral way"
+ geometry::convert(*boost::begin(range), centroid);
+ return false;
+ }
+ return true;
+}
+
+
+/*!
+ \brief Calculate the centroid of a ring.
+*/
+template<typename Ring, closure_selector Closure, typename Strategy>
+struct centroid_range_state
+{
+ static inline void apply(Ring const& ring,
+ Strategy const& strategy, typename Strategy::state_type& state)
+ {
+ typedef typename closeable_view<Ring const, Closure>::type view_type;
+
+ typedef typename boost::range_iterator<view_type const>::type iterator_type;
+
+ view_type view(ring);
+ iterator_type it = boost::begin(view);
+ iterator_type end = boost::end(view);
+
+ for (iterator_type previous = it++;
+ it != end;
+ ++previous, ++it)
+ {
+ strategy.apply(*previous, *it, state);
+ }
+ }
+};
+
+template<typename Range, typename Point, closure_selector Closure, typename Strategy>
+struct centroid_range
+{
+ static inline void apply(Range const& range, Point& centroid,
+ Strategy const& strategy)
+ {
+ if (range_ok(range, centroid))
+ {
+ typename Strategy::state_type state;
+ centroid_range_state
+ <
+ Range,
+ Closure,
+ Strategy
+ >::apply(range, strategy, state);
+ strategy.result(state, centroid);
+ }
+ }
+};
+
+
+/*!
+ \brief Centroid of a polygon.
+ \note Because outer ring is clockwise, inners are counter clockwise,
+ triangle approach is OK and works for polygons with rings.
+*/
+template<typename Polygon, typename Strategy>
+struct centroid_polygon_state
+{
+ typedef typename ring_type<Polygon>::type ring_type;
+
+ static inline void apply(Polygon const& poly,
+ Strategy const& strategy, typename Strategy::state_type& state)
+ {
+ typedef centroid_range_state
+ <
+ ring_type,
+ geometry::closure<ring_type>::value,
+ Strategy
+ > per_ring;
+
+ per_ring::apply(exterior_ring(poly), strategy, state);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ per_ring::apply(*it, strategy, state);
+ }
+ }
+};
+
+template<typename Polygon, typename Point, typename Strategy>
+struct centroid_polygon
+{
+ static inline void apply(Polygon const& poly, Point& centroid,
+ Strategy const& strategy)
+ {
+ if (range_ok(exterior_ring(poly), centroid))
+ {
+ typename Strategy::state_type state;
+ centroid_polygon_state
+ <
+ Polygon,
+ Strategy
+ >::apply(poly, strategy, state);
+ strategy.result(state, centroid);
+ }
+ }
+};
+
+
+}} // namespace detail::centroid
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename Point,
+ typename Strategy
+>
+struct centroid {};
+
+template
+<
+ typename Geometry,
+ typename Point,
+ typename Strategy
+>
+struct centroid<point_tag, Geometry, Point, Strategy>
+ : detail::centroid::centroid_point<Geometry, Point, Strategy>
+{};
+
+template
+<
+ typename Box,
+ typename Point,
+ typename Strategy
+>
+struct centroid<box_tag, Box, Point, Strategy>
+ : detail::centroid::centroid_box<Box, Point, Strategy>
+{};
+
+template <typename Ring, typename Point, typename Strategy>
+struct centroid<ring_tag, Ring, Point, Strategy>
+ : detail::centroid::centroid_range
+ <
+ Ring,
+ Point,
+ geometry::closure<Ring>::value,
+ Strategy
+ >
+{};
+
+template <typename Linestring, typename Point, typename Strategy>
+struct centroid<linestring_tag, Linestring, Point, Strategy>
+ : detail::centroid::centroid_range
+ <
+ Linestring,
+ Point,
+ closed,
+ Strategy
+ >
+ {};
+
+template <typename Polygon, typename Point, typename Strategy>
+struct centroid<polygon_tag, Polygon, Point, Strategy>
+ : detail::centroid::centroid_polygon<Polygon, Point, Strategy>
+ {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_calc{centroid} \brief_strategy
+\ingroup centroid
+\details \details_calc{centroid,geometric center (or: center of mass)}. \details_strategy_reasons
+\tparam Geometry \tparam_geometry
+\tparam Point \tparam_point
+\tparam Strategy \tparam_strategy{Centroid}
+\param geometry \param_geometry
+\param c \param_point \param_set{centroid}
+\param strategy \param_strategy{centroid}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/centroid.qbk]}
+\qbk{[include reference/algorithms/centroid_strategies.qbk]}
+}
+
+*/
+template<typename Geometry, typename Point, typename Strategy>
+inline void centroid(Geometry const& geometry, Point& c,
+ Strategy const& strategy)
+{
+ //BOOST_CONCEPT_ASSERT( (geometry::concept::CentroidStrategy<Strategy>) );
+
+ concept::check_concepts_and_equal_dimensions<Point, Geometry const>();
+
+ typedef typename point_type<Geometry>::type point_type;
+
+ // Call dispatch apply method. That one returns true if centroid
+ // should be taken from state.
+ dispatch::centroid
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Point,
+ Strategy
+ >::apply(geometry, c, strategy);
+}
+
+
+/*!
+\brief \brief_calc{centroid}
+\ingroup centroid
+\details \details_calc{centroid,geometric center (or: center of mass)}. \details_default_strategy
+\tparam Geometry \tparam_geometry
+\tparam Point \tparam_point
+\param geometry \param_geometry
+\param c The calculated centroid will be assigned to this point reference
+
+\qbk{[include reference/algorithms/centroid.qbk]}
+\qbk{
+[heading Example]
+[centroid]
+[centroid_output]
+}
+ */
+template<typename Geometry, typename Point>
+inline void centroid(Geometry const& geometry, Point& c)
+{
+ concept::check_concepts_and_equal_dimensions<Point, Geometry const>();
+
+ typedef typename strategy::centroid::services::default_strategy
+ <
+ typename cs_tag<Geometry>::type,
+ typename tag_cast
+ <
+ typename tag<Geometry>::type,
+ pointlike_tag,
+ linear_tag,
+ areal_tag
+ >::type,
+ dimension<Geometry>::type::value,
+ Point,
+ Geometry
+ >::type strategy_type;
+
+ centroid(geometry, c, strategy_type());
+}
+
+
+/*!
+\brief \brief_calc{centroid}
+\ingroup centroid
+\details \details_calc{centroid,geometric center (or: center of mass)}. \details_return{centroid}.
+\tparam Point \tparam_point
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{centroid}
+
+\qbk{[include reference/algorithms/centroid.qbk]}
+ */
+template<typename Point, typename Geometry>
+inline Point return_centroid(Geometry const& geometry)
+{
+ concept::check_concepts_and_equal_dimensions<Point, Geometry const>();
+
+ Point c;
+ centroid(geometry, c);
+ return c;
+}
+
+/*!
+\brief \brief_calc{centroid} \brief_strategy
+\ingroup centroid
+\details \details_calc{centroid,geometric center (or: center of mass)}. \details_return{centroid}. \details_strategy_reasons
+\tparam Point \tparam_point
+\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{centroid}
+\param geometry \param_geometry
+\param strategy \param_strategy{centroid}
+\return \return_calc{centroid}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/centroid.qbk]}
+\qbk{[include reference/algorithms/centroid_strategies.qbk]}
+ */
+template<typename Point, typename Geometry, typename Strategy>
+inline Point return_centroid(Geometry const& geometry, Strategy const& strategy)
+{
+ //BOOST_CONCEPT_ASSERT( (geometry::concept::CentroidStrategy<Strategy>) );
+
+ concept::check_concepts_and_equal_dimensions<Point, Geometry const>();
+
+ Point c;
+ centroid(geometry, c, strategy);
+ return c;
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_CENTROID_HPP
diff --git a/src/boost/geometry/algorithms/clear.hpp b/src/boost/geometry/algorithms/clear.hpp
new file mode 100644
index 0000000..d733658
--- /dev/null
+++ b/src/boost/geometry/algorithms/clear.hpp
@@ -0,0 +1,159 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_CLEAR_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_CLEAR_HPP
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace clear
+{
+
+template <typename Geometry>
+struct collection_clear
+{
+ static inline void apply(Geometry& geometry)
+ {
+ traits::clear<Geometry>::apply(geometry);
+ }
+};
+
+template <typename Polygon>
+struct polygon_clear
+{
+ static inline void apply(Polygon& polygon)
+ {
+ traits::clear
+ <
+ typename boost::remove_reference
+ <
+ typename traits::interior_mutable_type<Polygon>::type
+ >::type
+ >::apply(interior_rings(polygon));
+ traits::clear
+ <
+ typename boost::remove_reference
+ <
+ typename traits::ring_mutable_type<Polygon>::type
+ >::type
+ >::apply(exterior_ring(polygon));
+ }
+};
+
+template <typename Geometry>
+struct no_action
+{
+ static inline void apply(Geometry& )
+ {
+ }
+};
+
+}} // namespace detail::clear
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry,
+ typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
+>
+struct clear
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+// Point/box/segment do not have clear. So specialize to do nothing.
+template <typename Geometry>
+struct clear<Geometry, point_tag>
+ : detail::clear::no_action<Geometry>
+{};
+
+template <typename Geometry>
+struct clear<Geometry, box_tag>
+ : detail::clear::no_action<Geometry>
+{};
+
+template <typename Geometry>
+struct clear<Geometry, segment_tag>
+ : detail::clear::no_action<Geometry>
+{};
+
+template <typename Geometry>
+struct clear<Geometry, linestring_tag>
+ : detail::clear::collection_clear<Geometry>
+{};
+
+template <typename Geometry>
+struct clear<Geometry, ring_tag>
+ : detail::clear::collection_clear<Geometry>
+{};
+
+
+// Polygon can (indirectly) use std for clear
+template <typename Polygon>
+struct clear<Polygon, polygon_tag>
+ : detail::clear::polygon_clear<Polygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Clears a linestring, ring or polygon (exterior+interiors) or multi*
+\details Generic function to clear a geometry. All points will be removed from the collection or collections
+ making up the geometry. In most cases this is equivalent to the .clear() method of a std::vector<...>. In
+ the case of a polygon, this clear functionality is automatically called for the exterior ring, and for the
+ interior ring collection. In the case of a point, boxes and segments, nothing will happen.
+\ingroup clear
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry which will be cleared
+\note points and boxes cannot be cleared, instead they can be set to zero by "assign_zero"
+
+\qbk{[include reference/algorithms/clear.qbk]}
+*/
+template <typename Geometry>
+inline void clear(Geometry& geometry)
+{
+ concept::check<Geometry>();
+
+ dispatch::clear<Geometry>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_CLEAR_HPP
diff --git a/src/boost/geometry/algorithms/comparable_distance.hpp b/src/boost/geometry/algorithms/comparable_distance.hpp
new file mode 100644
index 0000000..3467045
--- /dev/null
+++ b/src/boost/geometry/algorithms/comparable_distance.hpp
@@ -0,0 +1,74 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_COMPARABLE_DISTANCE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_COMPARABLE_DISTANCE_HPP
+
+
+#include <boost/geometry/algorithms/distance.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief \brief_calc2{comparable distance measurement}
+\ingroup distance
+\details The free function comparable_distance does not necessarily calculate the distance,
+ but it calculates a distance measure such that two distances are comparable to each other.
+ For example: for the Cartesian coordinate system, Pythagoras is used but the square root
+ is not taken, which makes it faster and the results of two point pairs can still be
+ compared to each other.
+\tparam Geometry1 first geometry type
+\tparam Geometry2 second geometry type
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return \return_calc{comparable distance}
+
+\qbk{[include reference/algorithms/comparable_distance.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline typename default_distance_result<Geometry1, Geometry2>::type comparable_distance(
+ Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ typedef typename point_type<Geometry1>::type point1_type;
+ typedef typename point_type<Geometry2>::type point2_type;
+
+ // Define a point-point-distance-strategy
+ // for either the normal case, either the reversed case
+
+ typedef typename strategy::distance::services::comparable_type
+ <
+ typename boost::mpl::if_c
+ <
+ geometry::reverse_dispatch
+ <Geometry1, Geometry2>::type::value,
+ typename strategy::distance::services::default_strategy
+ <point_tag, point2_type, point1_type>::type,
+ typename strategy::distance::services::default_strategy
+ <point_tag, point1_type, point2_type>::type
+ >::type
+ >::type strategy_type;
+
+ return distance(geometry1, geometry2, strategy_type());
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_COMPARABLE_DISTANCE_HPP
diff --git a/src/boost/geometry/algorithms/convert.hpp b/src/boost/geometry/algorithms/convert.hpp
new file mode 100644
index 0000000..fbbf74c
--- /dev/null
+++ b/src/boost/geometry/algorithms/convert.hpp
@@ -0,0 +1,411 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_CONVERT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_CONVERT_HPP
+
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/is_array.hpp>
+
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/algorithms/append.hpp>
+#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/for_each.hpp>
+#include <boost/geometry/algorithms/detail/assign_values.hpp>
+#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
+#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp>
+
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace conversion
+{
+
+template
+<
+ typename Point,
+ typename Box,
+ std::size_t Index,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct point_to_box
+{
+ static inline void apply(Point const& point, Box& box)
+ {
+ typedef typename coordinate_type<Box>::type coordinate_type;
+
+ set<Index, Dimension>(box,
+ boost::numeric_cast<coordinate_type>(get<Dimension>(point)));
+ point_to_box
+ <
+ Point, Box,
+ Index, Dimension + 1, DimensionCount
+ >::apply(point, box);
+ }
+};
+
+
+template
+<
+ typename Point,
+ typename Box,
+ std::size_t Index,
+ std::size_t DimensionCount
+>
+struct point_to_box<Point, Box, Index, DimensionCount, DimensionCount>
+{
+ static inline void apply(Point const& , Box& )
+ {}
+};
+
+template <typename Box, typename Range, bool Close, bool Reverse>
+struct box_to_range
+{
+ static inline void apply(Box const& box, Range& range)
+ {
+ traits::resize<Range>::apply(range, Close ? 5 : 4);
+ assign_box_corners_oriented<Reverse>(box, range);
+ if (Close)
+ {
+ range[4] = range[0];
+ }
+ }
+};
+
+template <typename Segment, typename Range>
+struct segment_to_range
+{
+ static inline void apply(Segment const& segment, Range& range)
+ {
+ traits::resize<Range>::apply(range, 2);
+
+ typename boost::range_iterator<Range>::type it = boost::begin(range);
+
+ assign_point_from_index<0>(segment, *it);
+ ++it;
+ assign_point_from_index<1>(segment, *it);
+ }
+};
+
+template
+<
+ typename Range1,
+ typename Range2,
+ bool Reverse = false
+>
+struct range_to_range
+{
+ typedef typename reversible_view
+ <
+ Range1 const,
+ Reverse ? iterate_reverse : iterate_forward
+ >::type rview_type;
+ typedef typename closeable_view
+ <
+ rview_type const,
+ geometry::closure<Range1>::value
+ >::type view_type;
+
+ static inline void apply(Range1 const& source, Range2& destination)
+ {
+ geometry::clear(destination);
+
+ rview_type rview(source);
+
+ // We consider input always as closed, and skip last
+ // point for open output.
+ view_type view(rview);
+
+ int n = boost::size(view);
+ if (geometry::closure<Range2>::value == geometry::open)
+ {
+ n--;
+ }
+
+ int i = 0;
+ for (typename boost::range_iterator<view_type const>::type it
+ = boost::begin(view);
+ it != boost::end(view) && i < n;
+ ++it, ++i)
+ {
+ geometry::append(destination, *it);
+ }
+ }
+};
+
+template <typename Polygon1, typename Polygon2>
+struct polygon_to_polygon
+{
+ typedef range_to_range
+ <
+ typename geometry::ring_type<Polygon1>::type,
+ typename geometry::ring_type<Polygon2>::type,
+ geometry::point_order<Polygon1>::value
+ != geometry::point_order<Polygon2>::value
+ > per_ring;
+
+ static inline void apply(Polygon1 const& source, Polygon2& destination)
+ {
+ // Clearing managed per ring, and in the resizing of interior rings
+
+ per_ring::apply(geometry::exterior_ring(source),
+ geometry::exterior_ring(destination));
+
+ // Container should be resizeable
+ traits::resize
+ <
+ typename boost::remove_reference
+ <
+ typename traits::interior_mutable_type<Polygon2>::type
+ >::type
+ >::apply(interior_rings(destination), num_interior_rings(source));
+
+ typename interior_return_type<Polygon1 const>::type rings_source
+ = interior_rings(source);
+ typename interior_return_type<Polygon2>::type rings_dest
+ = interior_rings(destination);
+
+ BOOST_AUTO_TPL(it_source, boost::begin(rings_source));
+ BOOST_AUTO_TPL(it_dest, boost::begin(rings_dest));
+
+ for ( ; it_source != boost::end(rings_source); ++it_source, ++it_dest)
+ {
+ per_ring::apply(*it_source, *it_dest);
+ }
+ }
+};
+
+
+}} // namespace detail::conversion
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename Tag1 = typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
+ typename Tag2 = typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
+ std::size_t DimensionCount = dimension<Geometry1>::type::value,
+ bool UseAssignment = boost::is_same<Geometry1, Geometry2>::value
+ && !boost::is_array<Geometry1>::value
+>
+struct convert: not_implemented<Tag1, Tag2, mpl::int_<DimensionCount> >
+{};
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename Tag,
+ std::size_t DimensionCount
+>
+struct convert<Geometry1, Geometry2, Tag, Tag, DimensionCount, true>
+{
+ // Same geometry type -> copy whole geometry
+ static inline void apply(Geometry1 const& source, Geometry2& destination)
+ {
+ destination = source;
+ }
+};
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ std::size_t DimensionCount
+>
+struct convert<Geometry1, Geometry2, point_tag, point_tag, DimensionCount, false>
+ : detail::conversion::point_to_point<Geometry1, Geometry2, 0, DimensionCount>
+{};
+
+
+template
+<
+ typename Box1, typename Box2,
+ std::size_t DimensionCount
+>
+struct convert<Box1, Box2, box_tag, box_tag, DimensionCount, false>
+ : detail::conversion::indexed_to_indexed<Box1, Box2, 0, DimensionCount>
+{};
+
+
+template
+<
+ typename Segment1, typename Segment2,
+ std::size_t DimensionCount
+>
+struct convert<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, false>
+ : detail::conversion::indexed_to_indexed<Segment1, Segment2, 0, DimensionCount>
+{};
+
+
+template <typename Segment, typename LineString, std::size_t DimensionCount>
+struct convert<Segment, LineString, segment_tag, linestring_tag, DimensionCount, false>
+ : detail::conversion::segment_to_range<Segment, LineString>
+{};
+
+
+template <typename Ring1, typename Ring2, std::size_t DimensionCount>
+struct convert<Ring1, Ring2, ring_tag, ring_tag, DimensionCount, false>
+ : detail::conversion::range_to_range
+ <
+ Ring1,
+ Ring2,
+ geometry::point_order<Ring1>::value
+ != geometry::point_order<Ring2>::value
+ >
+{};
+
+template <typename LineString1, typename LineString2, std::size_t DimensionCount>
+struct convert<LineString1, LineString2, linestring_tag, linestring_tag, DimensionCount, false>
+ : detail::conversion::range_to_range<LineString1, LineString2>
+{};
+
+template <typename Polygon1, typename Polygon2, std::size_t DimensionCount>
+struct convert<Polygon1, Polygon2, polygon_tag, polygon_tag, DimensionCount, false>
+ : detail::conversion::polygon_to_polygon<Polygon1, Polygon2>
+{};
+
+template <typename Box, typename Ring>
+struct convert<Box, Ring, box_tag, ring_tag, 2, false>
+ : detail::conversion::box_to_range
+ <
+ Box,
+ Ring,
+ geometry::closure<Ring>::value == closed,
+ geometry::point_order<Ring>::value == counterclockwise
+ >
+{};
+
+
+template <typename Box, typename Polygon>
+struct convert<Box, Polygon, box_tag, polygon_tag, 2, false>
+{
+ static inline void apply(Box const& box, Polygon& polygon)
+ {
+ typedef typename ring_type<Polygon>::type ring_type;
+
+ convert
+ <
+ Box, ring_type,
+ box_tag, ring_tag,
+ 2, false
+ >::apply(box, exterior_ring(polygon));
+ }
+};
+
+
+template <typename Point, typename Box, std::size_t DimensionCount>
+struct convert<Point, Box, point_tag, box_tag, DimensionCount, false>
+{
+ static inline void apply(Point const& point, Box& box)
+ {
+ detail::conversion::point_to_box
+ <
+ Point, Box, min_corner, 0, DimensionCount
+ >::apply(point, box);
+ detail::conversion::point_to_box
+ <
+ Point, Box, max_corner, 0, DimensionCount
+ >::apply(point, box);
+ }
+};
+
+
+template <typename Ring, typename Polygon, std::size_t DimensionCount>
+struct convert<Ring, Polygon, ring_tag, polygon_tag, DimensionCount, false>
+{
+ static inline void apply(Ring const& ring, Polygon& polygon)
+ {
+ typedef typename ring_type<Polygon>::type ring_type;
+ convert
+ <
+ Ring, ring_type,
+ ring_tag, ring_tag,
+ DimensionCount, false
+ >::apply(ring, exterior_ring(polygon));
+ }
+};
+
+
+template <typename Polygon, typename Ring, std::size_t DimensionCount>
+struct convert<Polygon, Ring, polygon_tag, ring_tag, DimensionCount, false>
+{
+ static inline void apply(Polygon const& polygon, Ring& ring)
+ {
+ typedef typename ring_type<Polygon>::type ring_type;
+
+ convert
+ <
+ ring_type, Ring,
+ ring_tag, ring_tag,
+ DimensionCount, false
+ >::apply(exterior_ring(polygon), ring);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Converts one geometry to another geometry
+\details The convert algorithm converts one geometry, e.g. a BOX, to another
+geometry, e.g. a RING. This only if it is possible and applicable.
+If the point-order is different, or the closure is different between two
+geometry types, it will be converted correctly by explicitly reversing the
+points or closing or opening the polygon rings.
+\ingroup convert
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry (source)
+\param geometry2 \param_geometry (target)
+
+\qbk{[include reference/algorithms/convert.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline void convert(Geometry1 const& geometry1, Geometry2& geometry2)
+{
+ concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2>();
+
+ dispatch::convert<Geometry1, Geometry2>::apply(geometry1, geometry2);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_CONVERT_HPP
diff --git a/src/boost/geometry/algorithms/convex_hull.hpp b/src/boost/geometry/algorithms/convex_hull.hpp
new file mode 100644
index 0000000..56b87c8
--- /dev/null
+++ b/src/boost/geometry/algorithms/convex_hull.hpp
@@ -0,0 +1,275 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP
+
+#include <boost/array.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/strategies/convex_hull.hpp>
+#include <boost/geometry/strategies/concepts/convex_hull_concept.hpp>
+
+#include <boost/geometry/views/detail/range_type.hpp>
+
+#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/detail/as_range.hpp>
+#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace convex_hull
+{
+
+template
+<
+ typename Geometry,
+ order_selector Order,
+ typename Strategy
+>
+struct hull_insert
+{
+
+ // Member template function (to avoid inconvenient declaration
+ // of output-iterator-type, from hull_to_geometry)
+ template <typename OutputIterator>
+ static inline OutputIterator apply(Geometry const& geometry,
+ OutputIterator out, Strategy const& strategy)
+ {
+ typename Strategy::state_type state;
+
+ strategy.apply(geometry, state);
+ strategy.result(state, out, Order == clockwise);
+ return out;
+ }
+};
+
+template
+<
+ typename Geometry,
+ typename Strategy
+>
+struct hull_to_geometry
+{
+ template <typename OutputGeometry>
+ static inline void apply(Geometry const& geometry, OutputGeometry& out,
+ Strategy const& strategy)
+ {
+ hull_insert
+ <
+ Geometry,
+ geometry::point_order<OutputGeometry>::value,
+ Strategy
+ >::apply(geometry,
+ std::back_inserter(
+ // Handle linestring, ring and polygon the same:
+ detail::as_range
+ <
+ typename range_type<OutputGeometry>::type
+ >(out)), strategy);
+ }
+};
+
+
+// Helper metafunction for default strategy retrieval
+template <typename Geometry>
+struct default_strategy
+ : strategy_convex_hull
+ <
+ Geometry,
+ typename point_type<Geometry>::type
+ >
+{};
+
+
+}} // namespace detail::convex_hull
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Geometry,
+ typename Strategy = typename detail::convex_hull::default_strategy<Geometry>::type,
+ typename Tag = typename tag<Geometry>::type
+>
+struct convex_hull
+ : detail::convex_hull::hull_to_geometry<Geometry, Strategy>
+{};
+
+template
+<
+ typename Box,
+ typename Strategy
+>
+struct convex_hull<Box, Strategy, box_tag>
+{
+ template <typename OutputGeometry>
+ static inline void apply(Box const& box, OutputGeometry& out,
+ Strategy const& )
+ {
+ static bool const Close
+ = geometry::closure<OutputGeometry>::value == closed;
+ static bool const Reverse
+ = geometry::point_order<OutputGeometry>::value == counterclockwise;
+
+ // A hull for boxes is trivial. Any strategy is (currently) skipped.
+ boost::array<typename point_type<Box>::type, 4> range;
+ geometry::detail::assign_box_corners_oriented<Reverse>(box, range);
+ geometry::append(out, range);
+ if (Close)
+ {
+ geometry::append(out, *boost::begin(range));
+ }
+ }
+};
+
+
+
+template
+<
+ order_selector Order,
+ typename Geometry, typename Strategy
+>
+struct convex_hull_insert
+ : detail::convex_hull::hull_insert<Geometry, Order, Strategy>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template<typename Geometry, typename OutputGeometry, typename Strategy>
+inline void convex_hull(Geometry const& geometry,
+ OutputGeometry& out, Strategy const& strategy)
+{
+ concept::check_concepts_and_equal_dimensions
+ <
+ const Geometry,
+ OutputGeometry
+ >();
+
+ BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
+
+ if (geometry::num_points(geometry) == 0)
+ {
+ // Leave output empty
+ return;
+ }
+
+ dispatch::convex_hull
+ <
+ Geometry,
+ Strategy
+ >::apply(geometry, out, strategy);
+}
+
+
+/*!
+\brief \brief_calc{convex hull}
+\ingroup convex_hull
+\details \details_calc{convex_hull,convex hull}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry \param_geometry, input geometry
+\param hull \param_geometry \param_set{convex hull}
+
+\qbk{[include reference/algorithms/convex_hull.qbk]}
+ */
+template<typename Geometry, typename OutputGeometry>
+inline void convex_hull(Geometry const& geometry,
+ OutputGeometry& hull)
+{
+ concept::check_concepts_and_equal_dimensions
+ <
+ const Geometry,
+ OutputGeometry
+ >();
+
+ typedef typename detail::convex_hull::default_strategy<Geometry>::type strategy_type;
+
+ convex_hull(geometry, hull, strategy_type());
+}
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace convex_hull
+{
+
+
+template<typename Geometry, typename OutputIterator, typename Strategy>
+inline OutputIterator convex_hull_insert(Geometry const& geometry,
+ OutputIterator out, Strategy const& strategy)
+{
+ // Concept: output point type = point type of input geometry
+ concept::check<Geometry const>();
+ concept::check<typename point_type<Geometry>::type>();
+
+ BOOST_CONCEPT_ASSERT( (geometry::concept::ConvexHullStrategy<Strategy>) );
+
+ return dispatch::convex_hull_insert
+ <
+ geometry::point_order<Geometry>::value,
+ Geometry, Strategy
+ >::apply(geometry, out, strategy);
+}
+
+
+/*!
+\brief Calculate the convex hull of a geometry, output-iterator version
+\ingroup convex_hull
+\tparam Geometry the input geometry type
+\tparam OutputIterator: an output-iterator
+\param geometry the geometry to calculate convex hull from
+\param out an output iterator outputing points of the convex hull
+\note This overloaded version outputs to an output iterator.
+In this case, nothing is known about its point-type or
+ about its clockwise order. Therefore, the input point-type
+ and order are copied
+
+ */
+template<typename Geometry, typename OutputIterator>
+inline OutputIterator convex_hull_insert(Geometry const& geometry,
+ OutputIterator out)
+{
+ // Concept: output point type = point type of input geometry
+ concept::check<Geometry const>();
+ concept::check<typename point_type<Geometry>::type>();
+
+ typedef typename detail::convex_hull::default_strategy<Geometry>::type strategy_type;
+
+ return convex_hull_insert(geometry, out, strategy_type());
+}
+
+
+}} // namespace detail::convex_hull
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_CONVEX_HULL_HPP
diff --git a/src/boost/geometry/algorithms/correct.hpp b/src/boost/geometry/algorithms/correct.hpp
new file mode 100644
index 0000000..583e395
--- /dev/null
+++ b/src/boost/geometry/algorithms/correct.hpp
@@ -0,0 +1,265 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_CORRECT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_CORRECT_HPP
+
+
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/util/order_as_direction.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace correct
+{
+
+template <typename Geometry>
+struct correct_nop
+{
+ static inline void apply(Geometry& )
+ {}
+};
+
+
+template <typename Box, std::size_t Dimension, std::size_t DimensionCount>
+struct correct_box_loop
+{
+ typedef typename coordinate_type<Box>::type coordinate_type;
+
+ static inline void apply(Box& box)
+ {
+ if (get<min_corner, Dimension>(box) > get<max_corner, Dimension>(box))
+ {
+ // Swap the coordinates
+ coordinate_type max_value = get<min_corner, Dimension>(box);
+ coordinate_type min_value = get<max_corner, Dimension>(box);
+ set<min_corner, Dimension>(box, min_value);
+ set<max_corner, Dimension>(box, max_value);
+ }
+
+ correct_box_loop
+ <
+ Box, Dimension + 1, DimensionCount
+ >::apply(box);
+ }
+};
+
+
+
+template <typename Box, std::size_t DimensionCount>
+struct correct_box_loop<Box, DimensionCount, DimensionCount>
+{
+ static inline void apply(Box& )
+ {}
+
+};
+
+
+// Correct a box: make min/max correct
+template <typename Box>
+struct correct_box
+{
+
+ static inline void apply(Box& box)
+ {
+ // Currently only for Cartesian coordinates
+ // (or spherical without crossing dateline)
+ // Future version: adapt using strategies
+ correct_box_loop
+ <
+ Box, 0, dimension<Box>::type::value
+ >::apply(box);
+ }
+};
+
+
+// Close a ring, if not closed
+template <typename Ring, typename Predicate>
+struct correct_ring
+{
+ typedef typename point_type<Ring>::type point_type;
+ typedef typename coordinate_type<Ring>::type coordinate_type;
+
+ typedef typename strategy::area::services::default_strategy
+ <
+ typename cs_tag<point_type>::type,
+ point_type
+ >::type strategy_type;
+
+ typedef detail::area::ring_area
+ <
+ Ring,
+ order_as_direction<geometry::point_order<Ring>::value>::value,
+ geometry::closure<Ring>::value,
+ strategy_type
+ > ring_area_type;
+
+
+ static inline void apply(Ring& r)
+ {
+ // Check close-ness
+ if (boost::size(r) > 2)
+ {
+ // check if closed, if not, close it
+ bool const disjoint = geometry::disjoint(*boost::begin(r), *(boost::end(r) - 1));
+ closure_selector const s = geometry::closure<Ring>::value;
+
+ if (disjoint && (s == closed))
+ {
+ geometry::append(r, *boost::begin(r));
+ }
+ if (! disjoint && geometry::closure<Ring>::value != closed)
+ {
+ // Open it by removing last point
+ geometry::traits::resize<Ring>::apply(r, boost::size(r) - 1);
+ }
+ }
+ // Check area
+ Predicate predicate;
+ typedef typename default_area_result<Ring>::type area_result_type;
+ area_result_type const zero = area_result_type();
+ if (predicate(ring_area_type::apply(r, strategy_type()), zero))
+ {
+ std::reverse(boost::begin(r), boost::end(r));
+ }
+ }
+};
+
+// Correct a polygon: normalizes all rings, sets outer ring clockwise, sets all
+// inner rings counter clockwise (or vice versa depending on orientation)
+template <typename Polygon>
+struct correct_polygon
+{
+ typedef typename ring_type<Polygon>::type ring_type;
+ typedef typename default_area_result<Polygon>::type area_result_type;
+
+ static inline void apply(Polygon& poly)
+ {
+ correct_ring
+ <
+ ring_type,
+ std::less<area_result_type>
+ >::apply(exterior_ring(poly));
+
+ typename interior_return_type<Polygon>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ correct_ring
+ <
+ ring_type,
+ std::greater<area_result_type>
+ >::apply(*it);
+ }
+ }
+};
+
+
+}} // namespace detail::correct
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry, typename Tag = typename tag<Geometry>::type>
+struct correct: not_implemented<Tag>
+{};
+
+template <typename Point>
+struct correct<Point, point_tag>
+ : detail::correct::correct_nop<Point>
+{};
+
+template <typename LineString>
+struct correct<LineString, linestring_tag>
+ : detail::correct::correct_nop<LineString>
+{};
+
+template <typename Segment>
+struct correct<Segment, segment_tag>
+ : detail::correct::correct_nop<Segment>
+{};
+
+
+template <typename Box>
+struct correct<Box, box_tag>
+ : detail::correct::correct_box<Box>
+{};
+
+template <typename Ring>
+struct correct<Ring, ring_tag>
+ : detail::correct::correct_ring
+ <
+ Ring,
+ std::less<typename default_area_result<Ring>::type>
+ >
+{};
+
+template <typename Polygon>
+struct correct<Polygon, polygon_tag>
+ : detail::correct::correct_polygon<Polygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Corrects a geometry
+\details Corrects a geometry: all rings which are wrongly oriented with respect
+ to their expected orientation are reversed. To all rings which do not have a
+ closing point and are typed as they should have one, the first point is
+ appended. Also boxes can be corrected.
+\ingroup correct
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry which will be corrected if necessary
+
+\qbk{[include reference/algorithms/correct.qbk]}
+*/
+template <typename Geometry>
+inline void correct(Geometry& geometry)
+{
+ concept::check<Geometry const>();
+
+ dispatch::correct<Geometry>::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_CORRECT_HPP
diff --git a/src/boost/geometry/algorithms/covered_by.hpp b/src/boost/geometry/algorithms/covered_by.hpp
new file mode 100644
index 0000000..c3c406c
--- /dev/null
+++ b/src/boost/geometry/algorithms/covered_by.hpp
@@ -0,0 +1,195 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
+
+
+#include <cstddef>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Tag1 = typename tag<Geometry1>::type,
+ typename Tag2 = typename tag<Geometry2>::type
+>
+struct covered_by: not_implemented<Tag1, Tag2>
+{};
+
+
+template <typename Point, typename Box>
+struct covered_by<Point, Box, point_tag, box_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
+ {
+ return strategy.apply(point, box);
+ }
+};
+
+template <typename Box1, typename Box2>
+struct covered_by<Box1, Box2, box_tag, box_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
+ {
+ assert_dimension_equal<Box1, Box2>();
+ return strategy.apply(box1, box2);
+ }
+};
+
+
+
+template <typename Point, typename Ring>
+struct covered_by<Point, Ring, point_tag, ring_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
+ {
+ return detail::within::point_in_ring
+ <
+ Point,
+ Ring,
+ order_as_direction<geometry::point_order<Ring>::value>::value,
+ geometry::closure<Ring>::value,
+ Strategy
+ >::apply(point, ring, strategy) >= 0;
+ }
+};
+
+template <typename Point, typename Polygon>
+struct covered_by<Point, Polygon, point_tag, polygon_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
+ {
+ return detail::within::point_in_polygon
+ <
+ Point,
+ Polygon,
+ order_as_direction<geometry::point_order<Polygon>::value>::value,
+ geometry::closure<Polygon>::value,
+ Strategy
+ >::apply(point, polygon, strategy) >= 0;
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_check12{is inside or on border}
+\ingroup covered_by
+\details \details_check12{covered_by, is inside or on border}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry which might be inside or on the border of the second geometry
+\param geometry2 \param_geometry which might cover the first geometry
+\return true if geometry1 is inside of or on the border of geometry2,
+ else false
+\note The default strategy is used for covered_by detection
+
+\qbk{[include reference/algorithms/covered_by.qbk]}
+
+ */
+template<typename Geometry1, typename Geometry2>
+inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typedef typename point_type<Geometry1>::type point_type1;
+ typedef typename point_type<Geometry2>::type point_type2;
+
+ typedef typename strategy::covered_by::services::default_strategy
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag<Geometry1>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ typename tag_cast
+ <
+ typename cs_tag<point_type1>::type, spherical_tag
+ >::type,
+ typename tag_cast
+ <
+ typename cs_tag<point_type2>::type, spherical_tag
+ >::type,
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
+ return dispatch::covered_by
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, strategy_type());
+}
+
+/*!
+\brief \brief_check12{is inside or on border} \brief_strategy
+\ingroup covered_by
+\details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry which might be inside or on the border of the second geometry
+\param geometry2 \param_geometry which might cover the first geometry
+\param strategy strategy to be used
+\return true if geometry1 is inside of or on the border of geometry2,
+ else false
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/covered_by.qbk]}
+
+*/
+template<typename Geometry1, typename Geometry2, typename Strategy>
+inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ concept::within::check
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ Strategy
+ >();
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ return dispatch::covered_by
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, strategy);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
diff --git a/src/boost/geometry/algorithms/detail/as_range.hpp b/src/boost/geometry/algorithms/detail/as_range.hpp
new file mode 100644
index 0000000..d0dfb07
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/as_range.hpp
@@ -0,0 +1,107 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP
+
+
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/util/add_const_if_c.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry, typename Range, bool IsConst>
+struct as_range
+{
+ static inline typename add_const_if_c<IsConst, Range>::type& get(
+ typename add_const_if_c<IsConst, Geometry>::type& input)
+ {
+ return input;
+ }
+};
+
+
+template <typename Geometry, typename Range, bool IsConst>
+struct as_range<polygon_tag, Geometry, Range, IsConst>
+{
+ static inline typename add_const_if_c<IsConst, Range>::type& get(
+ typename add_const_if_c<IsConst, Geometry>::type& input)
+ {
+ return exterior_ring(input);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+// Will probably be replaced by the more generic "view_as", therefore in detail
+namespace detail
+{
+
+/*!
+\brief Function getting either the range (ring, linestring) itself
+or the outer ring (polygon)
+\details Utility to handle polygon's outer ring as a range
+\ingroup utility
+*/
+template <typename Range, typename Geometry>
+inline Range& as_range(Geometry& input)
+{
+ return dispatch::as_range
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Range,
+ false
+ >::get(input);
+}
+
+
+/*!
+\brief Function getting either the range (ring, linestring) itself
+or the outer ring (polygon), const version
+\details Utility to handle polygon's outer ring as a range
+\ingroup utility
+*/
+template <typename Range, typename Geometry>
+inline Range const& as_range(Geometry const& input)
+{
+ return dispatch::as_range
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Range,
+ true
+ >::get(input);
+}
+
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_AS_RANGE_HPP
diff --git a/src/boost/geometry/algorithms/detail/assign_box_corners.hpp b/src/boost/geometry/algorithms/detail/assign_box_corners.hpp
new file mode 100644
index 0000000..1fd4173
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/assign_box_corners.hpp
@@ -0,0 +1,93 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_BOX_CORNERS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_BOX_CORNERS_HPP
+
+
+#include <cstddef>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/algorithms/detail/assign_values.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+// Note: this is moved to namespace detail because the names and parameter orders
+// are not yet 100% clear.
+
+/*!
+\brief Assign the four points of a 2D box
+\ingroup assign
+\note The order is crucial. Most logical is LOWER, UPPER and sub-order LEFT, RIGHT
+ so this is how it is implemented.
+\tparam Box \tparam_box
+\tparam Point \tparam_point
+\param box \param_box
+\param lower_left point being assigned to lower left coordinates of the box
+\param lower_right point being assigned to lower right coordinates of the box
+\param upper_left point being assigned to upper left coordinates of the box
+\param upper_right point being assigned to upper right coordinates of the box
+
+\qbk{
+[heading Example]
+[assign_box_corners] [assign_box_corners_output]
+}
+*/
+template <typename Box, typename Point>
+inline void assign_box_corners(Box const& box,
+ Point& lower_left, Point& lower_right,
+ Point& upper_left, Point& upper_right)
+{
+ concept::check<Box const>();
+ concept::check<Point>();
+
+ detail::assign::assign_box_2d_corner
+ <min_corner, min_corner>(box, lower_left);
+ detail::assign::assign_box_2d_corner
+ <max_corner, min_corner>(box, lower_right);
+ detail::assign::assign_box_2d_corner
+ <min_corner, max_corner>(box, upper_left);
+ detail::assign::assign_box_2d_corner
+ <max_corner, max_corner>(box, upper_right);
+}
+
+template <bool Reverse, typename Box, typename Range>
+inline void assign_box_corners_oriented(Box const& box, Range& corners)
+{
+ if (Reverse)
+ {
+ // make counterclockwise ll,lr,ur,ul
+ assign_box_corners(box, corners[0], corners[1], corners[3], corners[2]);
+ }
+ else
+ {
+ // make clockwise ll,ul,ur,lr
+ assign_box_corners(box, corners[0], corners[3], corners[1], corners[2]);
+ }
+}
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_BOX_CORNERS_HPP
diff --git a/src/boost/geometry/algorithms/detail/assign_indexed_point.hpp b/src/boost/geometry/algorithms/detail/assign_indexed_point.hpp
new file mode 100644
index 0000000..a1cffb8
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/assign_indexed_point.hpp
@@ -0,0 +1,94 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_INDEXED_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_INDEXED_POINT_HPP
+
+
+#include <cstddef>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/algorithms/detail/assign_values.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+/*!
+\brief Assign a box or segment with the value of a point
+\ingroup assign
+\tparam Index indicates which box-corner, min_corner (0) or max_corner (1)
+ or which point of segment (0/1)
+\tparam Point \tparam_point
+\tparam Geometry \tparam_box_or_segment
+\param point \param_point
+\param geometry \param_box_or_segment
+
+\qbk{
+[heading Example]
+[assign_point_to_index] [assign_point_to_index_output]
+}
+*/
+template <std::size_t Index, typename Geometry, typename Point>
+inline void assign_point_to_index(Point const& point, Geometry& geometry)
+{
+ concept::check<Point const>();
+ concept::check<Geometry>();
+
+ detail::assign::assign_point_to_index
+ <
+ Geometry, Point, Index, 0, dimension<Geometry>::type::value
+ >::apply(point, geometry);
+}
+
+
+/*!
+\brief Assign a point with a point of a box or segment
+\ingroup assign
+\tparam Index indicates which box-corner, min_corner (0) or max_corner (1)
+ or which point of segment (0/1)
+\tparam Geometry \tparam_box_or_segment
+\tparam Point \tparam_point
+\param geometry \param_box_or_segment
+\param point \param_point
+
+\qbk{
+[heading Example]
+[assign_point_from_index] [assign_point_from_index_output]
+}
+*/
+template <std::size_t Index, typename Point, typename Geometry>
+inline void assign_point_from_index(Geometry const& geometry, Point& point)
+{
+ concept::check<Geometry const>();
+ concept::check<Point>();
+
+ detail::assign::assign_point_from_index
+ <
+ Geometry, Point, Index, 0, dimension<Geometry>::type::value
+ >::apply(geometry, point);
+}
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ASSIGN_INDEXED_POINT_HPP
diff --git a/src/boost/geometry/algorithms/detail/assign_values.hpp b/src/boost/geometry/algorithms/detail/assign_values.hpp
new file mode 100644
index 0000000..ed47134
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/assign_values.hpp
@@ -0,0 +1,443 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
+
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/numeric/conversion/bounds.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/algorithms/append.hpp>
+#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+#include <boost/geometry/util/for_each_coordinate.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace assign
+{
+
+
+template
+<
+ typename Box, std::size_t Index,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct initialize
+{
+ typedef typename coordinate_type<Box>::type coordinate_type;
+
+ static inline void apply(Box& box, coordinate_type const& value)
+ {
+ geometry::set<Index, Dimension>(box, value);
+ initialize<Box, Index, Dimension + 1, DimensionCount>::apply(box, value);
+ }
+};
+
+
+template <typename Box, std::size_t Index, std::size_t DimensionCount>
+struct initialize<Box, Index, DimensionCount, DimensionCount>
+{
+ typedef typename coordinate_type<Box>::type coordinate_type;
+
+ static inline void apply(Box&, coordinate_type const& )
+ {}
+};
+
+
+template <typename Point>
+struct assign_zero_point
+{
+ static inline void apply(Point& point)
+ {
+ geometry::assign_value(point, 0);
+ }
+};
+
+
+template <typename BoxOrSegment>
+struct assign_inverse_box_or_segment
+{
+ typedef typename point_type<BoxOrSegment>::type point_type;
+
+ static inline void apply(BoxOrSegment& geometry)
+ {
+ typedef typename coordinate_type<point_type>::type bound_type;
+
+ initialize
+ <
+ BoxOrSegment, 0, 0, dimension<BoxOrSegment>::type::value
+ >::apply(
+ geometry, boost::numeric::bounds<bound_type>::highest());
+ initialize
+ <
+ BoxOrSegment, 1, 0, dimension<BoxOrSegment>::type::value
+ >::apply(
+ geometry, boost::numeric::bounds<bound_type>::lowest());
+ }
+};
+
+
+template <typename BoxOrSegment>
+struct assign_zero_box_or_segment
+{
+ static inline void apply(BoxOrSegment& geometry)
+ {
+ typedef typename coordinate_type<BoxOrSegment>::type coordinate_type;
+
+ initialize
+ <
+ BoxOrSegment, 0, 0, dimension<BoxOrSegment>::type::value
+ >::apply(geometry, coordinate_type());
+ initialize
+ <
+ BoxOrSegment, 1, 0, dimension<BoxOrSegment>::type::value
+ >::apply(geometry, coordinate_type());
+ }
+};
+
+
+template
+<
+ std::size_t Corner1, std::size_t Corner2,
+ typename Box, typename Point
+>
+inline void assign_box_2d_corner(Box const& box, Point& point)
+{
+ // Be sure both are 2-Dimensional
+ assert_dimension<Box, 2>();
+ assert_dimension<Point, 2>();
+
+ // Copy coordinates
+ typedef typename coordinate_type<Point>::type coordinate_type;
+
+ geometry::set<0>(point, boost::numeric_cast<coordinate_type>(get<Corner1, 0>(box)));
+ geometry::set<1>(point, boost::numeric_cast<coordinate_type>(get<Corner2, 1>(box)));
+}
+
+
+
+template
+<
+ typename Geometry, typename Point,
+ std::size_t Index,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct assign_point_to_index
+{
+
+ static inline void apply(Point const& point, Geometry& geometry)
+ {
+ geometry::set<Index, Dimension>(geometry, boost::numeric_cast
+ <
+ typename coordinate_type<Geometry>::type
+ >(geometry::get<Dimension>(point)));
+
+ assign_point_to_index
+ <
+ Geometry, Point, Index, Dimension + 1, DimensionCount
+ >::apply(point, geometry);
+ }
+};
+
+template
+<
+ typename Geometry, typename Point,
+ std::size_t Index,
+ std::size_t DimensionCount
+>
+struct assign_point_to_index
+ <
+ Geometry, Point,
+ Index,
+ DimensionCount, DimensionCount
+ >
+{
+ static inline void apply(Point const& , Geometry& )
+ {
+ }
+};
+
+
+template
+<
+ typename Geometry, typename Point,
+ std::size_t Index,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct assign_point_from_index
+{
+
+ static inline void apply(Geometry const& geometry, Point& point)
+ {
+ geometry::set<Dimension>( point, boost::numeric_cast
+ <
+ typename coordinate_type<Point>::type
+ >(geometry::get<Index, Dimension>(geometry)));
+
+ assign_point_from_index
+ <
+ Geometry, Point, Index, Dimension + 1, DimensionCount
+ >::apply(geometry, point);
+ }
+};
+
+template
+<
+ typename Geometry, typename Point,
+ std::size_t Index,
+ std::size_t DimensionCount
+>
+struct assign_point_from_index
+ <
+ Geometry, Point,
+ Index,
+ DimensionCount, DimensionCount
+ >
+{
+ static inline void apply(Geometry const&, Point&)
+ {
+ }
+};
+
+
+template <typename Geometry>
+struct assign_2d_box_or_segment
+{
+ typedef typename coordinate_type<Geometry>::type coordinate_type;
+
+ // Here we assign 4 coordinates to a box of segment
+ // -> Most logical is: x1,y1,x2,y2
+ // In case the user reverses x1/x2 or y1/y2, for a box, we could reverse them (THAT IS NOT IMPLEMENTED)
+
+ template <typename Type>
+ static inline void apply(Geometry& geometry,
+ Type const& x1, Type const& y1, Type const& x2, Type const& y2)
+ {
+ geometry::set<0, 0>(geometry, boost::numeric_cast<coordinate_type>(x1));
+ geometry::set<0, 1>(geometry, boost::numeric_cast<coordinate_type>(y1));
+ geometry::set<1, 0>(geometry, boost::numeric_cast<coordinate_type>(x2));
+ geometry::set<1, 1>(geometry, boost::numeric_cast<coordinate_type>(y2));
+ }
+};
+
+
+}} // namespace detail::assign
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename Geometry, std::size_t DimensionCount>
+struct assign
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+template <typename Point>
+struct assign<point_tag, Point, 2>
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+
+ template <typename T>
+ static inline void apply(Point& point, T const& c1, T const& c2)
+ {
+ set<0>(point, boost::numeric_cast<coordinate_type>(c1));
+ set<1>(point, boost::numeric_cast<coordinate_type>(c2));
+ }
+};
+
+template <typename Point>
+struct assign<point_tag, Point, 3>
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+
+ template <typename T>
+ static inline void apply(Point& point, T const& c1, T const& c2, T const& c3)
+ {
+ set<0>(point, boost::numeric_cast<coordinate_type>(c1));
+ set<1>(point, boost::numeric_cast<coordinate_type>(c2));
+ set<2>(point, boost::numeric_cast<coordinate_type>(c3));
+ }
+};
+
+template <typename Box>
+struct assign<box_tag, Box, 2>
+ : detail::assign::assign_2d_box_or_segment<Box>
+{};
+
+template <typename Segment>
+struct assign<segment_tag, Segment, 2>
+ : detail::assign::assign_2d_box_or_segment<Segment>
+{};
+
+
+
+template <typename GeometryTag, typename Geometry>
+struct assign_zero {};
+
+
+template <typename Point>
+struct assign_zero<point_tag, Point>
+ : detail::assign::assign_zero_point<Point>
+{};
+
+template <typename Box>
+struct assign_zero<box_tag, Box>
+ : detail::assign::assign_zero_box_or_segment<Box>
+{};
+
+template <typename Segment>
+struct assign_zero<segment_tag, Segment>
+ : detail::assign::assign_zero_box_or_segment<Segment>
+{};
+
+
+template <typename GeometryTag, typename Geometry>
+struct assign_inverse {};
+
+template <typename Box>
+struct assign_inverse<box_tag, Box>
+ : detail::assign::assign_inverse_box_or_segment<Box>
+{};
+
+template <typename Segment>
+struct assign_inverse<segment_tag, Segment>
+ : detail::assign::assign_inverse_box_or_segment<Segment>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Assign two coordinates to a geometry (usually a 2D point)
+\ingroup assign
+\tparam Geometry \tparam_geometry
+\tparam Type \tparam_numeric to specify the coordinates
+\param geometry \param_geometry
+\param c1 \param_x
+\param c2 \param_y
+
+\qbk{distinguish, 2 coordinate values}
+\qbk{
+[heading Example]
+[assign_2d_point] [assign_2d_point_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make]
+}
+ */
+template <typename Geometry, typename Type>
+inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2)
+{
+ concept::check<Geometry>();
+
+ dispatch::assign
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ geometry::dimension<Geometry>::type::value
+ >::apply(geometry, c1, c2);
+}
+
+/*!
+\brief Assign three values to a geometry (usually a 3D point)
+\ingroup assign
+\tparam Geometry \tparam_geometry
+\tparam Type \tparam_numeric to specify the coordinates
+\param geometry \param_geometry
+\param c1 \param_x
+\param c2 \param_y
+\param c3 \param_z
+
+\qbk{distinguish, 3 coordinate values}
+\qbk{
+[heading Example]
+[assign_3d_point] [assign_3d_point_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make]
+}
+ */
+template <typename Geometry, typename Type>
+inline void assign_values(Geometry& geometry,
+ Type const& c1, Type const& c2, Type const& c3)
+{
+ concept::check<Geometry>();
+
+ dispatch::assign
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ geometry::dimension<Geometry>::type::value
+ >::apply(geometry, c1, c2, c3);
+}
+
+/*!
+\brief Assign four values to a geometry (usually a box or segment)
+\ingroup assign
+\tparam Geometry \tparam_geometry
+\tparam Type \tparam_numeric to specify the coordinates
+\param geometry \param_geometry
+\param c1 First coordinate (usually x1)
+\param c2 Second coordinate (usually y1)
+\param c3 Third coordinate (usually x2)
+\param c4 Fourth coordinate (usually y2)
+
+\qbk{distinguish, 4 coordinate values}
+ */
+template <typename Geometry, typename Type>
+inline void assign_values(Geometry& geometry,
+ Type const& c1, Type const& c2, Type const& c3, Type const& c4)
+{
+ concept::check<Geometry>();
+
+ dispatch::assign
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ geometry::dimension<Geometry>::type::value
+ >::apply(geometry, c1, c2, c3, c4);
+}
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
diff --git a/src/boost/geometry/algorithms/detail/calculate_null.hpp b/src/boost/geometry/algorithms/detail/calculate_null.hpp
new file mode 100644
index 0000000..4b48d62
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/calculate_null.hpp
@@ -0,0 +1,38 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template<typename ReturnType, typename Geometry, typename Strategy>
+struct calculate_null
+{
+ static inline ReturnType apply(Geometry const& , Strategy const&)
+ {
+ return ReturnType();
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
diff --git a/src/boost/geometry/algorithms/detail/calculate_sum.hpp b/src/boost/geometry/algorithms/detail/calculate_sum.hpp
new file mode 100644
index 0000000..2ad3490
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/calculate_sum.hpp
@@ -0,0 +1,64 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
+
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template
+<
+ typename ReturnType,
+ typename Polygon,
+ typename Strategy,
+ typename Policy
+>
+class calculate_polygon_sum
+{
+ template <typename Rings>
+ static inline ReturnType sum_interior_rings(Rings const& rings, Strategy const& strategy)
+ {
+ ReturnType sum = ReturnType();
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ sum += Policy::apply(*it, strategy);
+ }
+ return sum;
+ }
+
+public :
+ static inline ReturnType apply(Polygon const& poly, Strategy const& strategy)
+ {
+ return Policy::apply(exterior_ring(poly), strategy)
+ + sum_interior_rings(interior_rings(poly), strategy)
+ ;
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
diff --git a/src/boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp b/src/boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp
new file mode 100644
index 0000000..d39824a
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp
@@ -0,0 +1,80 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_INDEXED_TO_INDEXED_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_INDEXED_TO_INDEXED_HPP
+
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace conversion
+{
+
+
+template
+<
+ typename Source,
+ typename Destination,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct indexed_to_indexed
+{
+ static inline void apply(Source const& source, Destination& destination)
+ {
+ typedef typename coordinate_type<Destination>::type coordinate_type;
+
+ geometry::set<min_corner, Dimension>(destination,
+ boost::numeric_cast<coordinate_type>(
+ geometry::get<min_corner, Dimension>(source)));
+ geometry::set<max_corner, Dimension>(destination,
+ boost::numeric_cast<coordinate_type>(
+ geometry::get<max_corner, Dimension>(source)));
+
+ indexed_to_indexed
+ <
+ Source, Destination,
+ Dimension + 1, DimensionCount
+ >::apply(source, destination);
+ }
+};
+
+template
+<
+ typename Source,
+ typename Destination,
+ std::size_t DimensionCount
+>
+struct indexed_to_indexed<Source, Destination, DimensionCount, DimensionCount>
+{
+ static inline void apply(Source const& , Destination& )
+ {}
+};
+
+
+}} // namespace detail::conversion
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_INDEXED_TO_INDEXED_HPP
diff --git a/src/boost/geometry/algorithms/detail/convert_point_to_point.hpp b/src/boost/geometry/algorithms/detail/convert_point_to_point.hpp
new file mode 100644
index 0000000..c7d37b6
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/convert_point_to_point.hpp
@@ -0,0 +1,68 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_POINT_TO_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_POINT_TO_POINT_HPP
+
+// Note: extracted from "convert.hpp" to avoid circular references convert/append
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace conversion
+{
+
+
+template <typename Source, typename Destination, std::size_t Dimension, std::size_t DimensionCount>
+struct point_to_point
+{
+ static inline void apply(Source const& source, Destination& destination)
+ {
+ typedef typename coordinate_type<Destination>::type coordinate_type;
+
+ set<Dimension>(destination, boost::numeric_cast<coordinate_type>(get<Dimension>(source)));
+ point_to_point<Source, Destination, Dimension + 1, DimensionCount>::apply(source, destination);
+ }
+};
+
+template <typename Source, typename Destination, std::size_t DimensionCount>
+struct point_to_point<Source, Destination, DimensionCount, DimensionCount>
+{
+ static inline void apply(Source const& , Destination& )
+ {}
+};
+
+
+template <typename Source, typename Destination>
+inline void convert_point_to_point(Source const& source, Destination& destination)
+{
+ point_to_point<Source, Destination, 0, dimension<Destination>::value>::apply(source, destination);
+}
+
+
+
+}} // namespace detail::conversion
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CONVERT_POINT_TO_POINT_HPP
diff --git a/src/boost/geometry/algorithms/detail/disjoint.hpp b/src/boost/geometry/algorithms/detail/disjoint.hpp
new file mode 100644
index 0000000..2ced5b1
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/disjoint.hpp
@@ -0,0 +1,225 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_HPP
+
+// Note: contrary to most files, the geometry::detail::disjoint namespace
+// is partly implemented in a separate file, to avoid circular references
+// disjoint -> get_turns -> disjoint
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/reverse_dispatch.hpp>
+
+
+#include <boost/geometry/util/math.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace disjoint
+{
+
+
+struct disjoint_interrupt_policy
+{
+ static bool const enabled = true;
+ bool has_intersections;
+
+ inline disjoint_interrupt_policy()
+ : has_intersections(false)
+ {}
+
+ template <typename Range>
+ inline bool apply(Range const& range)
+ {
+ // If there is any IP in the range, it is NOT disjoint
+ if (boost::size(range) > 0)
+ {
+ has_intersections = true;
+ return true;
+ }
+ return false;
+ }
+};
+
+
+
+template
+<
+ typename Point1, typename Point2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point
+{
+ static inline bool apply(Point1 const& p1, Point2 const& p2)
+ {
+ if (! geometry::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
+ {
+ return true;
+ }
+ return point_point
+ <
+ Point1, Point2,
+ Dimension + 1, DimensionCount
+ >::apply(p1, p2);
+ }
+};
+
+
+template <typename Point1, typename Point2, std::size_t DimensionCount>
+struct point_point<Point1, Point2, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Point1 const& , Point2 const& )
+ {
+ return false;
+ }
+};
+
+
+template
+<
+ typename Point, typename Box,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_box
+{
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ if (get<Dimension>(point) < get<min_corner, Dimension>(box)
+ || get<Dimension>(point) > get<max_corner, Dimension>(box))
+ {
+ return true;
+ }
+ return point_box
+ <
+ Point, Box,
+ Dimension + 1, DimensionCount
+ >::apply(point, box);
+ }
+};
+
+
+template <typename Point, typename Box, std::size_t DimensionCount>
+struct point_box<Point, Box, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Point const& , Box const& )
+ {
+ return false;
+ }
+};
+
+
+template
+<
+ typename Box1, typename Box2,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct box_box
+{
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
+ {
+ if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
+ {
+ return true;
+ }
+ if (get<min_corner, Dimension>(box1) > get<max_corner, Dimension>(box2))
+ {
+ return true;
+ }
+ return box_box
+ <
+ Box1, Box2,
+ Dimension + 1, DimensionCount
+ >::apply(box1, box2);
+ }
+};
+
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct box_box<Box1, Box2, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Box1 const& , Box2 const& )
+ {
+ return false;
+ }
+};
+
+
+
+/*!
+ \brief Internal utility function to detect of boxes are disjoint
+ \note Is used from other algorithms, declared separately
+ to avoid circular references
+ */
+template <typename Box1, typename Box2>
+inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2)
+{
+ return box_box
+ <
+ Box1, Box2,
+ 0, dimension<Box1>::type::value
+ >::apply(box1, box2);
+}
+
+
+
+/*!
+ \brief Internal utility function to detect of points are disjoint
+ \note To avoid circular references
+ */
+template <typename Point1, typename Point2>
+inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
+{
+ return point_point
+ <
+ Point1, Point2,
+ 0, dimension<Point1>::type::value
+ >::apply(point1, point2);
+}
+
+
+}} // namespace detail::disjoint
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace equals
+{
+
+/*!
+ \brief Internal utility function to detect of points are disjoint
+ \note To avoid circular references
+ */
+template <typename Point1, typename Point2>
+inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
+{
+ return ! detail::disjoint::disjoint_point_point(point1, point2);
+}
+
+
+}} // namespace detail::equals
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_HPP
diff --git a/src/boost/geometry/algorithms/detail/equals/collect_vectors.hpp b/src/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
new file mode 100644
index 0000000..9c2fe28
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/equals/collect_vectors.hpp
@@ -0,0 +1,315 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
+
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+// TODO: if Boost.LA of Emil Dotchevski is accepted, adapt this
+template <typename T>
+struct collected_vector
+{
+ typedef T type;
+
+ inline collected_vector()
+ {}
+
+ inline collected_vector(T const& px, T const& py,
+ T const& pdx, T const& pdy)
+ : x(px)
+ , y(py)
+ , dx(pdx)
+ , dy(pdy)
+ , dx_0(T())
+ , dy_0(T())
+ {}
+
+ T x, y;
+ T dx, dy;
+ T dx_0, dy_0;
+
+ // For sorting
+ inline bool operator<(collected_vector<T> const& other) const
+ {
+ if (math::equals(x, other.x))
+ {
+ if (math::equals(y, other.y))
+ {
+ if (math::equals(dx, other.dx))
+ {
+ return dy < other.dy;
+ }
+ return dx < other.dx;
+ }
+ return y < other.y;
+ }
+ return x < other.x;
+ }
+
+ inline bool same_direction(collected_vector<T> const& other) const
+ {
+ // For high precision arithmetic, we have to be
+ // more relaxed then using ==
+ // Because 2/sqrt( (0,0)<->(2,2) ) == 1/sqrt( (0,0)<->(1,1) )
+ // is not always true (at least, it is not for ttmath)
+ return math::equals_with_epsilon(dx, other.dx)
+ && math::equals_with_epsilon(dy, other.dy);
+ }
+
+ // For std::equals
+ inline bool operator==(collected_vector<T> const& other) const
+ {
+ return math::equals(x, other.x)
+ && math::equals(y, other.y)
+ && same_direction(other);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace collect_vectors
+{
+
+
+template <typename Range, typename Collection>
+struct range_collect_vectors
+{
+ typedef typename boost::range_value<Collection>::type item_type;
+ typedef typename item_type::type calculation_type;
+
+ static inline void apply(Collection& collection, Range const& range)
+ {
+ if (boost::size(range) < 2)
+ {
+ return;
+ }
+
+ typedef typename boost::range_iterator<Range const>::type iterator;
+
+ bool first = true;
+ iterator it = boost::begin(range);
+
+ for (iterator prev = it++;
+ it != boost::end(range);
+ prev = it++)
+ {
+ typename boost::range_value<Collection>::type v;
+
+ v.x = get<0>(*prev);
+ v.y = get<1>(*prev);
+ v.dx = get<0>(*it) - v.x;
+ v.dy = get<1>(*it) - v.y;
+ v.dx_0 = v.dx;
+ v.dy_0 = v.dy;
+
+ // Normalize the vector -> this results in points+direction
+ // and is comparible between geometries
+ calculation_type magnitude = sqrt(
+ boost::numeric_cast<calculation_type>(v.dx * v.dx + v.dy * v.dy));
+
+ // Avoid non-duplicate points (AND division by zero)
+ if (magnitude > 0)
+ {
+ v.dx /= magnitude;
+ v.dy /= magnitude;
+
+ // Avoid non-direction changing points
+ if (first || ! v.same_direction(collection.back()))
+ {
+ collection.push_back(v);
+ }
+ first = false;
+ }
+ }
+
+ // If first one has same direction as last one, remove first one
+ if (boost::size(collection) > 1
+ && collection.front().same_direction(collection.back()))
+ {
+ collection.erase(collection.begin());
+ }
+ }
+};
+
+
+template <typename Box, typename Collection>
+struct box_collect_vectors
+{
+ // Calculate on coordinate type, but if it is integer,
+ // then use double
+ typedef typename boost::range_value<Collection>::type item_type;
+ typedef typename item_type::type calculation_type;
+
+ static inline void apply(Collection& collection, Box const& box)
+ {
+ typename point_type<Box>::type lower_left, lower_right,
+ upper_left, upper_right;
+ geometry::detail::assign_box_corners(box, lower_left, lower_right,
+ upper_left, upper_right);
+
+ typedef typename boost::range_value<Collection>::type item;
+
+ collection.push_back(item(get<0>(lower_left), get<1>(lower_left), 0, 1));
+ collection.push_back(item(get<0>(upper_left), get<1>(upper_left), 1, 0));
+ collection.push_back(item(get<0>(upper_right), get<1>(upper_right), 0, -1));
+ collection.push_back(item(get<0>(lower_right), get<1>(lower_right), -1, 0));
+ }
+};
+
+
+template <typename Polygon, typename Collection>
+struct polygon_collect_vectors
+{
+ static inline void apply(Collection& collection, Polygon const& polygon)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ typedef range_collect_vectors<ring_type, Collection> per_range;
+ per_range::apply(collection, exterior_ring(polygon));
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ per_range::apply(collection, *it);
+ }
+ }
+};
+
+
+template <typename MultiGeometry, typename Collection, typename SinglePolicy>
+struct multi_collect_vectors
+{
+ static inline void apply(Collection& collection, MultiGeometry const& multi)
+ {
+ for (typename boost::range_iterator<MultiGeometry const>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ SinglePolicy::apply(collection, *it);
+ }
+ }
+};
+
+
+}} // namespace detail::collect_vectors
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename Collection,
+ typename Geometry
+>
+struct collect_vectors
+{
+ static inline void apply(Collection&, Geometry const&)
+ {}
+};
+
+
+template <typename Collection, typename Box>
+struct collect_vectors<box_tag, Collection, Box>
+ : detail::collect_vectors::box_collect_vectors<Box, Collection>
+{};
+
+
+
+template <typename Collection, typename Ring>
+struct collect_vectors<ring_tag, Collection, Ring>
+ : detail::collect_vectors::range_collect_vectors<Ring, Collection>
+{};
+
+
+template <typename Collection, typename LineString>
+struct collect_vectors<linestring_tag, Collection, LineString>
+ : detail::collect_vectors::range_collect_vectors<LineString, Collection>
+{};
+
+
+template <typename Collection, typename Polygon>
+struct collect_vectors<polygon_tag, Collection, Polygon>
+ : detail::collect_vectors::polygon_collect_vectors<Polygon, Collection>
+{};
+
+
+template <typename Collection, typename MultiPolygon>
+struct collect_vectors<multi_polygon_tag, Collection, MultiPolygon>
+ : detail::collect_vectors::multi_collect_vectors
+ <
+ MultiPolygon,
+ Collection,
+ detail::collect_vectors::polygon_collect_vectors
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ Collection
+ >
+ >
+{};
+
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+ \ingroup collect_vectors
+ \tparam Collection Collection type, should be e.g. std::vector<>
+ \tparam Geometry geometry type
+ \param collection the collection of vectors
+ \param geometry the geometry to make collect_vectors
+*/
+template <typename Collection, typename Geometry>
+inline void collect_vectors(Collection& collection, Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ dispatch::collect_vectors
+ <
+ typename tag<Geometry>::type,
+ Collection,
+ Geometry
+ >::apply(collection, geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
diff --git a/src/boost/geometry/algorithms/detail/for_each_range.hpp b/src/boost/geometry/algorithms/detail/for_each_range.hpp
new file mode 100644
index 0000000..7cb01fa
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/for_each_range.hpp
@@ -0,0 +1,149 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/concept/requires.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/util/add_const_if_c.hpp>
+#include <boost/geometry/views/box_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each
+{
+
+
+template <typename Range, typename Actor, bool IsConst>
+struct fe_range_range
+{
+ static inline void apply(
+ typename add_const_if_c<IsConst, Range>::type& range,
+ Actor& actor)
+ {
+ actor.apply(range);
+ }
+};
+
+
+template <typename Polygon, typename Actor, bool IsConst>
+struct fe_range_polygon
+{
+ static inline void apply(
+ typename add_const_if_c<IsConst, Polygon>::type& polygon,
+ Actor& actor)
+ {
+ actor.apply(exterior_ring(polygon));
+
+ // TODO: If some flag says true, also do the inner rings.
+ // for convex hull, it's not necessary
+ }
+};
+
+template <typename Box, typename Actor, bool IsConst>
+struct fe_range_box
+{
+ static inline void apply(
+ typename add_const_if_c<IsConst, Box>::type& box,
+ Actor& actor)
+ {
+ actor.apply(box_view<Box>(box));
+ }
+};
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename Actor,
+ bool IsConst
+>
+struct for_each_range
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename Linestring, typename Actor, bool IsConst>
+struct for_each_range<linestring_tag, Linestring, Actor, IsConst>
+ : detail::for_each::fe_range_range<Linestring, Actor, IsConst>
+{};
+
+
+template <typename Ring, typename Actor, bool IsConst>
+struct for_each_range<ring_tag, Ring, Actor, IsConst>
+ : detail::for_each::fe_range_range<Ring, Actor, IsConst>
+{};
+
+
+template <typename Polygon, typename Actor, bool IsConst>
+struct for_each_range<polygon_tag, Polygon, Actor, IsConst>
+ : detail::for_each::fe_range_polygon<Polygon, Actor, IsConst>
+{};
+
+template <typename Box, typename Actor, bool IsConst>
+struct for_each_range<box_tag, Box, Actor, IsConst>
+ : detail::for_each::fe_range_box<Box, Actor, IsConst>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+namespace detail
+{
+
+template <typename Geometry, typename Actor>
+inline void for_each_range(Geometry const& geometry, Actor& actor)
+{
+ dispatch::for_each_range
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Actor,
+ true
+ >::apply(geometry, actor);
+}
+
+
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
diff --git a/src/boost/geometry/algorithms/detail/get_left_turns.hpp b/src/boost/geometry/algorithms/detail/get_left_turns.hpp
new file mode 100644
index 0000000..62f0f7f
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/get_left_turns.hpp
@@ -0,0 +1,367 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
+
+#include <boost/geometry/iterators/ever_circling_iterator.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// TODO: move this to /util/
+template <typename T>
+static inline std::pair<T, T> ordered_pair(T const& first, T const& second)
+{
+ return first < second ? std::make_pair(first, second) : std::make_pair(second, first);
+}
+
+template <typename AngleInfo>
+inline void debug_left_turn(AngleInfo const& ai, AngleInfo const& previous)
+{
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
+ std::cout << "Angle: " << (ai.incoming ? "i" : "o")
+ << " " << si(ai.seg_id)
+ << " " << (math::r2d * (ai.angle) )
+ << " turn: " << ai.turn_index << "[" << ai.operation_index << "]"
+ ;
+
+ if (ai.turn_index != previous.turn_index
+ || ai.operation_index != previous.operation_index)
+ {
+ std::cout << " diff: " << math::r2d * math::abs(previous.angle - ai.angle);
+ }
+ std::cout << std::endl;
+#endif
+}
+
+template <typename AngleInfo>
+inline void debug_left_turn(std::string const& caption, AngleInfo const& ai, AngleInfo const& previous,
+ int code = -99, int code2 = -99, int code3 = -99, int code4 = -99)
+{
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
+ std::cout << " " << caption
+ << " turn: " << ai.turn_index << "[" << ai.operation_index << "]"
+ << " " << si(ai.seg_id)
+ << " " << (ai.incoming ? "i" : "o")
+ << " " << (math::r2d * (ai.angle) )
+ << " turn: " << previous.turn_index << "[" << previous.operation_index << "]"
+ << " " << si(previous.seg_id)
+ << " " << (previous.incoming ? "i" : "o")
+ << " " << (math::r2d * (previous.angle) )
+ ;
+
+ if (code != -99)
+ {
+ std::cout << " code: " << code << " , " << code2 << " , " << code3 << " , " << code4;
+ }
+ std::cout << std::endl;
+#endif
+}
+
+
+template <typename Operation>
+inline bool include_operation(Operation const& op,
+ segment_identifier const& outgoing_seg_id,
+ segment_identifier const& incoming_seg_id)
+{
+ return op.seg_id == outgoing_seg_id
+ && op.other_id == incoming_seg_id
+ && (op.operation == detail::overlay::operation_union
+ ||op.operation == detail::overlay::operation_continue)
+ ;
+}
+
+template <typename Turn>
+inline bool process_include(segment_identifier const& outgoing_seg_id, segment_identifier const& incoming_seg_id,
+ int turn_index, Turn& turn,
+ std::set<int>& keep_indices, int priority)
+{
+ bool result = false;
+ for (int i = 0; i < 2; i++)
+ {
+ if (include_operation(turn.operations[i], outgoing_seg_id, incoming_seg_id))
+ {
+ turn.operations[i].include_in_occupation_map = true;
+ if (priority > turn.priority)
+ {
+ turn.priority = priority;
+ }
+ keep_indices.insert(turn_index);
+ result = true;
+ }
+ }
+ return result;
+}
+
+template <typename AngleInfo, typename Turns, typename TurnSegmentIndices>
+inline bool include_left_turn_of_all(
+ AngleInfo const& outgoing, AngleInfo const& incoming,
+ Turns& turns, TurnSegmentIndices const& turn_segment_indices,
+ std::set<int>& keep_indices, int priority)
+{
+ segment_identifier const& outgoing_seg_id = turns[outgoing.turn_index].operations[outgoing.operation_index].seg_id;
+ segment_identifier const& incoming_seg_id = turns[incoming.turn_index].operations[incoming.operation_index].seg_id;
+
+ if (outgoing.turn_index == incoming.turn_index)
+ {
+ return process_include(outgoing_seg_id, incoming_seg_id, outgoing.turn_index, turns[outgoing.turn_index], keep_indices, priority);
+ }
+
+ bool result = false;
+ std::pair<segment_identifier, segment_identifier> pair = ordered_pair(outgoing_seg_id, incoming_seg_id);
+ auto it = turn_segment_indices.find(pair);
+ if (it != turn_segment_indices.end())
+ {
+ for (auto sit = it->second.begin(); sit != it->second.end(); ++sit)
+ {
+ if (process_include(outgoing_seg_id, incoming_seg_id, *sit, turns[*sit], keep_indices, priority))
+ {
+ result = true;
+ }
+ }
+ }
+ return result;
+}
+
+template <std::size_t Index, typename Turn>
+inline bool corresponds(Turn const& turn, segment_identifier const& seg_id)
+{
+ return turn.operations[Index].operation == detail::overlay::operation_union
+ && turn.operations[Index].seg_id == seg_id;
+}
+
+
+template <typename Turns, typename TurnSegmentIndices>
+inline bool prefer_by_other(Turns const& turns,
+ TurnSegmentIndices const& turn_segment_indices,
+ std::set<int>& indices)
+{
+ std::map<segment_identifier, int> map;
+ for (auto sit = indices.begin(); sit != indices.end(); ++sit)
+ {
+ map[turns[*sit].operations[0].seg_id]++;
+ map[turns[*sit].operations[1].seg_id]++;
+ }
+
+ std::set<segment_identifier> segment_occuring_once;
+ for (auto mit = map.begin(); mit != map.end(); ++mit)
+ {
+ if (mit->second == 1)
+ {
+ segment_occuring_once.insert(mit->first);
+ }
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_PREFER
+ std::cout << si(mit->first) << " " << mit->second << std::endl;
+#endif
+ }
+
+ if (segment_occuring_once.size() == 2)
+ {
+ // Try to find within all turns a turn with these two segments
+
+ std::set<segment_identifier>::const_iterator soo_it = segment_occuring_once.begin();
+ segment_identifier front = *soo_it;
+ soo_it++;
+ segment_identifier back = *soo_it;
+
+ std::pair<segment_identifier, segment_identifier> pair = ordered_pair(front, back);
+ auto it = turn_segment_indices.find(pair);
+ if (it != turn_segment_indices.end())
+ {
+ // debug_turns_by_indices("Found", it->second);
+ // Check which is the union/continue
+ segment_identifier good;
+ for (auto sit = it->second.begin(); sit != it->second.end(); ++sit)
+ {
+ if (turns[*sit].operations[0].operation == detail::overlay::operation_union)
+ {
+ good = turns[*sit].operations[0].seg_id;
+ }
+ else if (turns[*sit].operations[1].operation == detail::overlay::operation_union)
+ {
+ good = turns[*sit].operations[1].seg_id;
+ }
+ }
+
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_PREFER
+ std::cout << "Good: " << si(good) << std::endl;
+#endif
+
+ // Find in indexes-to-keep this segment with the union. Discard the other one
+ std::set<int> ok_indices;
+ for (auto sit = indices.begin(); sit != indices.end(); ++sit)
+ {
+ if (corresponds<0>(turns[*sit], good) || corresponds<1>(turns[*sit], good))
+ {
+ ok_indices.insert(*sit);
+ }
+ }
+ if (ok_indices.size() > 0 && ok_indices.size() < indices.size())
+ {
+ indices = ok_indices;
+ std::cout << "^";
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+template <typename Turns>
+inline void prefer_by_priority(Turns const& turns, std::set<int>& indices)
+{
+ // Find max prio
+ int min_prio = 1024, max_prio = 0;
+ for (auto sit = indices.begin(); sit != indices.end(); ++sit)
+ {
+ if (turns[*sit].priority > max_prio)
+ {
+ max_prio = turns[*sit].priority;
+ }
+ if (turns[*sit].priority < min_prio)
+ {
+ min_prio = turns[*sit].priority;
+ }
+ }
+
+ if (min_prio == max_prio)
+ {
+ return;
+ }
+
+ // Only keep indices with high prio
+ std::set<int> ok_indices;
+ for (auto sit = indices.begin(); sit != indices.end(); ++sit)
+ {
+ if (turns[*sit].priority >= max_prio)
+ {
+ ok_indices.insert(*sit);
+ }
+ }
+ if (ok_indices.size() > 0 && ok_indices.size() < indices.size())
+ {
+ indices = ok_indices;
+ std::cout << "%";
+ }
+}
+
+template <typename AngleInfo, typename Angles, typename Turns, typename TurnSegmentIndices>
+inline void calculate_left_turns(Angles const& angles,
+ Turns& turns, TurnSegmentIndices const& turn_segment_indices,
+ std::set<int>& keep_indices)
+{
+ bool debug_indicate_size = false;
+
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<typename AngleInfo::point_type>::type
+ >::type side_strategy;
+
+ std::size_t i = 0;
+ std::size_t n = boost::size(angles);
+
+ typedef geometry::ever_circling_range_iterator<Angles const> circling_iterator;
+ circling_iterator cit(angles);
+
+ debug_left_turn(*cit, *cit);
+ for(circling_iterator prev = cit++; i < n; prev = cit++, i++)
+ {
+ debug_left_turn(*cit, *prev);
+
+ bool const include = ! geometry::math::equals(prev->angle, cit->angle)
+ && ! prev->incoming
+ && cit->incoming;
+
+ if (include)
+ {
+ // Go back to possibly include more same left outgoing angles:
+ // Because we check on side too we can take a large "epsilon"
+ circling_iterator back = prev - 1;
+
+ typename AngleInfo::angle_type eps = 0.00001;
+ int b = 1;
+ for(std::size_t d = 0;
+ math::abs(prev->angle - back->angle) < eps
+ && ! back->incoming
+ && d < n;
+ d++)
+ {
+ --back;
+ ++b;
+ }
+
+ // Same but forward to possibly include more incoming angles
+ int f = 1;
+ circling_iterator forward = cit + 1;
+ for(std::size_t d = 0;
+ math::abs(cit->angle - forward->angle) < eps
+ && forward->incoming
+ && d < n;
+ d++)
+ {
+ ++forward;
+ ++f;
+ }
+
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
+ std::cout << "HANDLE " << b << "/" << f << " ANGLES" << std::endl;
+#endif
+ for(circling_iterator bit = prev; bit != back; --bit)
+ {
+ int code = side_strategy::apply(bit->direction_point, prev->intersection_point, prev->direction_point);
+ int code2 = side_strategy::apply(prev->direction_point, bit->intersection_point, bit->direction_point);
+ for(circling_iterator fit = cit; fit != forward; ++fit)
+ {
+ int code3 = side_strategy::apply(fit->direction_point, cit->intersection_point, cit->direction_point);
+ int code4 = side_strategy::apply(cit->direction_point, fit->intersection_point, fit->direction_point);
+
+ int priority = 2;
+ if (code == -1 && code2 == 1)
+ {
+ // This segment is lying right of the other one.
+ // Cannot ignore it (because of robustness, see a.o. #rt_p21 from unit test).
+ // But if we find more we can prefer later by priority
+ // (a.o. necessary for #rt_o2 from unit test)
+ priority = 1;
+ }
+
+ bool included = include_left_turn_of_all(*bit, *fit, turns, turn_segment_indices, keep_indices, priority);
+ debug_left_turn(included ? "KEEP" : "SKIP", *fit, *bit, code, code2, code3, code4);
+ }
+ }
+ }
+ }
+
+ if (debug_indicate_size)
+ {
+ std::cout << " size=" << keep_indices.size();
+ }
+
+ if (keep_indices.size() >= 2)
+ {
+ prefer_by_other(turns, turn_segment_indices, keep_indices);
+ }
+ if (keep_indices.size() >= 2)
+ {
+ prefer_by_priority(turns, keep_indices);
+ }
+}
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
diff --git a/src/boost/geometry/algorithms/detail/has_self_intersections.hpp b/src/boost/geometry/algorithms/detail/has_self_intersections.hpp
new file mode 100644
index 0000000..1e6215e
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/has_self_intersections.hpp
@@ -0,0 +1,120 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_HAS_SELF_INTERSECTIONS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_HAS_SELF_INTERSECTIONS_HPP
+
+#include <deque>
+
+#include <boost/range.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
+
+#include <boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp>
+
+#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
+# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
+# include <boost/geometry/io/dsv/write.hpp>
+#endif
+
+
+namespace boost { namespace geometry
+{
+
+
+#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
+
+/*!
+\brief Overlay Invalid Input Exception
+\ingroup overlay
+\details The overlay_invalid_input_exception is thrown at invalid input
+ */
+class overlay_invalid_input_exception : public geometry::exception
+{
+public:
+
+ inline overlay_invalid_input_exception() {}
+
+ virtual char const* what() const throw()
+ {
+ return "Boost.Geometry Overlay invalid input exception";
+ }
+};
+
+#endif
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+template <typename Geometry>
+inline bool has_self_intersections(Geometry const& geometry)
+{
+ typedef typename point_type<Geometry>::type point_type;
+ typedef detail::overlay::turn_info<point_type> turn_info;
+ std::deque<turn_info> turns;
+ detail::disjoint::disjoint_interrupt_policy policy;
+ geometry::self_turns<detail::overlay::assign_null_policy>(geometry, turns, policy);
+
+#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
+ bool first = true;
+#endif
+ for(typename std::deque<turn_info>::const_iterator it = boost::begin(turns);
+ it != boost::end(turns); ++it)
+ {
+ turn_info const& info = *it;
+ bool const both_union_turn =
+ info.operations[0].operation == detail::overlay::operation_union
+ && info.operations[1].operation == detail::overlay::operation_union;
+ bool const both_intersection_turn =
+ info.operations[0].operation == detail::overlay::operation_intersection
+ && info.operations[1].operation == detail::overlay::operation_intersection;
+
+ bool const valid = (both_union_turn || both_intersection_turn)
+ && (info.method == detail::overlay::method_touch
+ || info.method == detail::overlay::method_touch_interior);
+
+ if (! valid)
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
+ if (first)
+ {
+ std::cout << "turn points: " << std::endl;
+ first = false;
+ }
+ std::cout << method_char(info.method);
+ for (int i = 0; i < 2; i++)
+ {
+ std::cout << " " << operation_char(info.operations[i].operation);
+ }
+ std::cout << " " << geometry::dsv(info.point) << std::endl;
+#endif
+
+#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
+ throw overlay_invalid_input_exception();
+#endif
+ }
+
+ }
+ return false;
+}
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_HAS_SELF_INTERSECTIONS_HPP
+
diff --git a/src/boost/geometry/algorithms/detail/not.hpp b/src/boost/geometry/algorithms/detail/not.hpp
new file mode 100644
index 0000000..abc3a4e
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/not.hpp
@@ -0,0 +1,50 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NOT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NOT_HPP
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+
+/*!
+\brief Structure negating the result of specified policy
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Policy
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return Negation of the result of the policy
+ */
+template <typename Geometry1, typename Geometry2, typename Policy>
+struct not_
+{
+ static inline bool apply(Geometry1 const &geometry1, Geometry2 const& geometry2)
+ {
+ return ! Policy::apply(geometry1, geometry2);
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_NOT_HPP
diff --git a/src/boost/geometry/algorithms/detail/occupation_info.hpp b/src/boost/geometry/algorithms/detail/occupation_info.hpp
new file mode 100644
index 0000000..e147ba1
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/occupation_info.hpp
@@ -0,0 +1,329 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
+
+#if ! defined(NDEBUG)
+ #define BOOST_GEOMETRY_DEBUG_BUFFER_OCCUPATION
+#endif
+
+#include <algorithm>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/iterators/closing_iterator.hpp>
+
+#include <boost/geometry/algorithms/detail/get_left_turns.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P>
+class relaxed_less
+{
+ typedef typename geometry::coordinate_type<P>::type coordinate_type;
+
+ coordinate_type epsilon;
+
+public :
+
+ inline relaxed_less()
+ {
+ // TODO: adapt for ttmath, and maybe build the map in another way
+ // (e.g. exact constellations of segment-id's), maybe adaptive.
+ epsilon = std::numeric_limits<double>::epsilon() * 100.0;
+ }
+
+ inline bool operator()(P const& a, P const& b) const
+ {
+ coordinate_type const dx = math::abs(geometry::get<0>(a) - geometry::get<0>(b));
+ coordinate_type const dy = math::abs(geometry::get<1>(a) - geometry::get<1>(b));
+
+
+ if (dx < epsilon && dy < epsilon)
+ {
+ return false;
+ }
+ if (dx < epsilon)
+ {
+ return geometry::get<1>(a) < geometry::get<1>(b);
+ }
+
+ return geometry::get<0>(a) < geometry::get<0>(b);
+ }
+
+ inline bool equals(P const& a, P const& b) const
+ {
+ typedef typename geometry::coordinate_type<P>::type coordinate_type;
+
+ coordinate_type const dx = math::abs(geometry::get<0>(a) - geometry::get<0>(b));
+ coordinate_type const dy = math::abs(geometry::get<1>(a) - geometry::get<1>(b));
+
+ return dx < epsilon && dy < epsilon;
+ };
+};
+
+
+template <typename T, typename P1, typename P2>
+inline T calculate_angle(P1 const& from_point, P2 const& to_point)
+{
+ typedef P1 vector_type;
+ vector_type v = from_point;
+ geometry::subtract_point(v, to_point);
+ return atan2(geometry::get<1>(v), geometry::get<0>(v));
+}
+
+template <typename Iterator, typename Vector>
+inline Iterator advance_circular(Iterator it, Vector const& vector, segment_identifier& seg_id, bool forward = true)
+{
+ int const increment = forward ? 1 : -1;
+ if (it == boost::begin(vector) && increment < 0)
+ {
+ it = boost::end(vector);
+ seg_id.segment_index = boost::size(vector);
+ }
+ it += increment;
+ seg_id.segment_index += increment;
+ if (it == boost::end(vector))
+ {
+ seg_id.segment_index = 0;
+ it = boost::begin(vector);
+ }
+ return it;
+}
+
+template <typename Point, typename T>
+struct angle_info
+{
+ typedef T angle_type;
+ typedef Point point_type;
+
+ segment_identifier seg_id;
+ int turn_index;
+ int operation_index;
+ Point intersection_point;
+ Point direction_point;
+ T angle;
+ bool incoming;
+};
+
+template <typename AngleInfo>
+class occupation_info
+{
+ typedef std::vector<AngleInfo> collection_type;
+
+ struct angle_sort
+ {
+ inline bool operator()(AngleInfo const& left, AngleInfo const& right) const
+ {
+ // In this case we can compare even double using equals
+ // return geometry::math::equals(left.angle, right.angle)
+ return left.angle == right.angle
+ ? int(left.incoming) < int(right.incoming)
+ : left.angle < right.angle
+ ;
+ }
+ };
+
+public :
+ collection_type angles;
+private :
+ bool m_occupied;
+ bool m_calculated;
+
+ inline bool is_occupied()
+ {
+ if (boost::size(angles) <= 1)
+ {
+ return false;
+ }
+
+ std::sort(angles.begin(), angles.end(), angle_sort());
+
+ typedef geometry::closing_iterator<collection_type const> closing_iterator;
+ closing_iterator vit(angles);
+ closing_iterator end(angles, true);
+
+ closing_iterator prev = vit++;
+ for( ; vit != end; prev = vit++)
+ {
+ if (! geometry::math::equals(prev->angle, vit->angle)
+ && ! prev->incoming
+ && vit->incoming)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+public :
+ inline occupation_info()
+ : m_occupied(false)
+ , m_calculated(false)
+ {}
+
+ template <typename PointC, typename Point1, typename Point2>
+ inline void add(PointC const& map_point, Point1 const& direction_point, Point2 const& intersection_point,
+ int turn_index, int operation_index,
+ segment_identifier const& seg_id, bool incoming)
+ {
+ //std::cout << "-> adding angle " << geometry::wkt(direction_point) << " .. " << geometry::wkt(intersection_point) << " " << int(incoming) << std::endl;
+ if (geometry::equals(direction_point, intersection_point))
+ {
+ //std::cout << "EQUAL! Skipping" << std::endl;
+ return;
+ }
+
+ AngleInfo info;
+ info.incoming = incoming;
+ info.angle = calculate_angle<typename AngleInfo::angle_type>(direction_point, map_point);
+ info.seg_id = seg_id;
+ info.turn_index = turn_index;
+ info.operation_index = operation_index;
+ info.intersection_point = intersection_point;
+ info.direction_point = direction_point;
+ angles.push_back(info);
+
+ m_calculated = false;
+ }
+
+ inline bool occupied()
+ {
+ if (! m_calculated)
+ {
+ m_occupied = is_occupied();
+ m_calculated = true;
+ }
+ return m_occupied;
+ }
+
+ template <typename Turns, typename TurnSegmentIndices>
+ inline void get_left_turns(
+ Turns& turns, TurnSegmentIndices const& turn_segment_indices,
+ std::set<int>& keep_indices)
+ {
+ std::sort(angles.begin(), angles.end(), angle_sort());
+ calculate_left_turns<AngleInfo>(angles, turns, turn_segment_indices, keep_indices);
+ }
+};
+
+
+template <typename Point, typename Ring, typename Info>
+inline void add_incoming_and_outgoing_angles(Point const& map_point, Point const& intersection_point,
+ Ring const& ring,
+ int turn_index,
+ int operation_index,
+ segment_identifier seg_id,
+ Info& info)
+{
+ typedef typename boost::range_iterator
+ <
+ Ring const
+ >::type iterator_type;
+
+ int const n = boost::size(ring);
+ if (seg_id.segment_index >= n || seg_id.segment_index < 0)
+ {
+ return;
+ }
+
+ segment_identifier real_seg_id = seg_id;
+ iterator_type it = boost::begin(ring) + seg_id.segment_index;
+
+ // TODO: if we use turn-info ("to", "middle"), we know if to advance without resorting to equals
+ relaxed_less<Point> comparator;
+
+ if (comparator.equals(intersection_point, *it))
+ {
+ // It should be equal only once. But otherwise we skip it (in "add")
+ it = advance_circular(it, ring, seg_id, false);
+ }
+
+ info.add(map_point, *it, intersection_point, turn_index, operation_index, real_seg_id, true);
+
+ if (comparator.equals(intersection_point, *it))
+ {
+ it = advance_circular(it, ring, real_seg_id);
+ }
+ else
+ {
+ // Don't upgrade the ID
+ it = advance_circular(it, ring, seg_id);
+ }
+ for (int defensive_check = 0;
+ comparator.equals(intersection_point, *it) && defensive_check < n;
+ defensive_check++)
+ {
+ it = advance_circular(it, ring, real_seg_id);
+ }
+
+ info.add(map_point, *it, intersection_point, turn_index, operation_index, real_seg_id, false);
+}
+
+
+// Map in two senses of the word: it is a std::map where the key is a point.
+// Per point an "occupation_info" record is kept
+// Used for the buffer (but will also be used for intersections/unions having complex self-tangencies)
+template <typename Point, typename OccupationInfo>
+class occupation_map
+{
+public :
+ typedef std::map<Point, OccupationInfo, relaxed_less<Point> > map_type;
+
+ map_type map;
+ std::set<int> turn_indices;
+
+ inline OccupationInfo& find_or_insert(Point const& point, Point& mapped_point)
+ {
+ typename map_type::iterator it = map.find(point);
+ if (it == boost::end(map))
+ {
+ std::pair<typename map_type::iterator, bool> pair
+ = map.insert(std::make_pair(point, OccupationInfo()));
+ it = pair.first;
+ }
+ mapped_point = it->first;
+ return it->second;
+ }
+
+ inline bool contains(Point const& point) const
+ {
+ typename map_type::const_iterator it = map.find(point);
+ return it != boost::end(map);
+ }
+
+ inline bool contains_turn_index(int index) const
+ {
+ return turn_indices.count(index) > 0;
+ }
+
+ inline void insert_turn_index(int index)
+ {
+ turn_indices.insert(index);
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OCCUPATION_INFO_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/add_rings.hpp b/src/boost/geometry/algorithms/detail/overlay/add_rings.hpp
new file mode 100644
index 0000000..74595fe
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/add_rings.hpp
@@ -0,0 +1,160 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename RingCollection
+>
+inline void convert_and_add(GeometryOut& result,
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ RingCollection const& collection,
+ ring_identifier id,
+ bool reversed, bool append)
+{
+ typedef typename geometry::tag<Geometry1>::type tag1;
+ typedef typename geometry::tag<Geometry2>::type tag2;
+ typedef typename geometry::tag<GeometryOut>::type tag_out;
+
+ if (id.source_index == 0)
+ {
+ convert_ring<tag_out>::apply(result,
+ get_ring<tag1>::apply(id, geometry1),
+ append, reversed);
+ }
+ else if (id.source_index == 1)
+ {
+ convert_ring<tag_out>::apply(result,
+ get_ring<tag2>::apply(id, geometry2),
+ append, reversed);
+ }
+ else if (id.source_index == 2)
+ {
+ convert_ring<tag_out>::apply(result,
+ get_ring<void>::apply(id, collection),
+ append, reversed);
+ }
+}
+
+template
+<
+ typename GeometryOut,
+ typename SelectionMap,
+ typename Geometry1,
+ typename Geometry2,
+ typename RingCollection,
+ typename OutputIterator
+>
+inline OutputIterator add_rings(SelectionMap const& map,
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ RingCollection const& collection,
+ OutputIterator out)
+{
+ typedef typename SelectionMap::const_iterator iterator;
+ typedef typename SelectionMap::mapped_type property_type;
+ typedef typename property_type::area_type area_type;
+
+ area_type const zero = 0;
+ std::size_t const min_num_points = core_detail::closure::minimum_ring_size
+ <
+ geometry::closure
+ <
+ typename boost::range_value
+ <
+ RingCollection const
+ >::type
+ >::value
+ >::value;
+
+
+ for (iterator it = boost::begin(map);
+ it != boost::end(map);
+ ++it)
+ {
+ if (! it->second.discarded
+ && it->second.parent.source_index == -1)
+ {
+ GeometryOut result;
+ convert_and_add(result, geometry1, geometry2, collection,
+ it->first, it->second.reversed, false);
+
+ // Add children
+ for (typename std::vector<ring_identifier>::const_iterator child_it
+ = it->second.children.begin();
+ child_it != it->second.children.end();
+ ++child_it)
+ {
+ iterator mit = map.find(*child_it);
+ if (mit != map.end()
+ && ! mit->second.discarded)
+ {
+ convert_and_add(result, geometry1, geometry2, collection,
+ *child_it, mit->second.reversed, true);
+ }
+ }
+
+ // Only add rings if they satisfy minimal requirements.
+ // This cannot be done earlier (during traversal), not
+ // everything is figured out yet (sum of positive/negative rings)
+ // TODO: individual rings can still contain less than 3 points.
+ if (geometry::num_points(result) >= min_num_points
+ && math::larger(geometry::area(result), zero))
+ {
+ *out++ = result;
+ }
+ }
+ }
+ return out;
+}
+
+
+template
+<
+ typename GeometryOut,
+ typename SelectionMap,
+ typename Geometry,
+ typename RingCollection,
+ typename OutputIterator
+>
+inline OutputIterator add_rings(SelectionMap const& map,
+ Geometry const& geometry,
+ RingCollection const& collection,
+ OutputIterator out)
+{
+ Geometry empty;
+ return add_rings<GeometryOut>(map, geometry, empty, collection, out);
+}
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp b/src/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp
new file mode 100644
index 0000000..2c0f88e
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp
@@ -0,0 +1,53 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/append.hpp>
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+template <typename Range, typename Point>
+inline void append_no_duplicates(Range& range, Point const& point, bool force = false)
+{
+ if (boost::size(range) == 0
+ || force
+ || ! geometry::detail::equals::equals_point_point(*(boost::end(range)-1), point))
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
+ std::cout << " add: ("
+ << geometry::get<0>(point) << ", " << geometry::get<1>(point) << ")"
+ << std::endl;
+#endif
+ geometry::append(range, point);
+ }
+}
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/src/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
new file mode 100644
index 0000000..5063f49
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
@@ -0,0 +1,338 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+
+template
+<
+ typename Item,
+ typename Geometry1, typename Geometry2,
+ typename RingCollection
+>
+static inline bool within_selected_input(Item const& item2, ring_identifier const& ring_id,
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ RingCollection const& collection)
+{
+ typedef typename geometry::tag<Geometry1>::type tag1;
+ typedef typename geometry::tag<Geometry2>::type tag2;
+
+ switch (ring_id.source_index)
+ {
+ case 0 :
+ return geometry::within(item2.point,
+ get_ring<tag1>::apply(ring_id, geometry1));
+ break;
+ case 1 :
+ return geometry::within(item2.point,
+ get_ring<tag2>::apply(ring_id, geometry2));
+ break;
+ case 2 :
+ return geometry::within(item2.point,
+ get_ring<void>::apply(ring_id, collection));
+ break;
+ }
+ return false;
+}
+
+
+template <typename Point>
+struct ring_info_helper
+{
+ typedef typename geometry::default_area_result<Point>::type area_type;
+
+ ring_identifier id;
+ area_type real_area;
+ area_type abs_area;
+ model::box<Point> envelope;
+
+ inline ring_info_helper()
+ : real_area(0), abs_area(0)
+ {}
+
+ inline ring_info_helper(ring_identifier i, area_type a)
+ : id(i), real_area(a), abs_area(geometry::math::abs(a))
+ {}
+};
+
+
+struct ring_info_helper_get_box
+{
+ template <typename Box, typename InputItem>
+ static inline void apply(Box& total, InputItem const& item)
+ {
+ geometry::expand(total, item.envelope);
+ }
+};
+
+struct ring_info_helper_ovelaps_box
+{
+ template <typename Box, typename InputItem>
+ static inline bool apply(Box const& box, InputItem const& item)
+ {
+ return ! geometry::detail::disjoint::disjoint_box_box(box, item.envelope);
+ }
+};
+
+template <typename Geometry1, typename Geometry2, typename Collection, typename RingMap>
+struct assign_visitor
+{
+ typedef typename RingMap::mapped_type ring_info_type;
+
+ Geometry1 const& m_geometry1;
+ Geometry2 const& m_geometry2;
+ Collection const& m_collection;
+ RingMap& m_ring_map;
+ bool m_check_for_orientation;
+
+
+ inline assign_visitor(Geometry1 const& g1, Geometry2 const& g2, Collection const& c,
+ RingMap& map, bool check)
+ : m_geometry1(g1)
+ , m_geometry2(g2)
+ , m_collection(c)
+ , m_ring_map(map)
+ , m_check_for_orientation(check)
+ {}
+
+ template <typename Item>
+ inline void apply(Item const& outer, Item const& inner, bool first = true)
+ {
+ if (first && outer.real_area < 0)
+ {
+ // Reverse arguments
+ apply(inner, outer, false);
+ return;
+ }
+
+ if (math::larger(outer.real_area, 0))
+ {
+ if (inner.real_area < 0 || m_check_for_orientation)
+ {
+ ring_info_type& inner_in_map = m_ring_map[inner.id];
+
+ if (geometry::within(inner_in_map.point, outer.envelope)
+ && within_selected_input(inner_in_map, outer.id, m_geometry1, m_geometry2, m_collection)
+ )
+ {
+ // Only assign parent if that parent is smaller (or if it is the first)
+ if (inner_in_map.parent.source_index == -1
+ || outer.abs_area < inner_in_map.parent_area)
+ {
+ inner_in_map.parent = outer.id;
+ inner_in_map.parent_area = outer.abs_area;
+ }
+ }
+ }
+ }
+ }
+};
+
+
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename RingCollection,
+ typename RingMap
+>
+inline void assign_parents(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ RingCollection const& collection,
+ RingMap& ring_map,
+ bool check_for_orientation = false)
+{
+ typedef typename geometry::tag<Geometry1>::type tag1;
+ typedef typename geometry::tag<Geometry2>::type tag2;
+
+ typedef typename RingMap::mapped_type ring_info_type;
+ typedef typename ring_info_type::point_type point_type;
+ typedef model::box<point_type> box_type;
+
+ typedef typename RingMap::iterator map_iterator_type;
+
+ {
+ typedef ring_info_helper<point_type> helper;
+ typedef std::vector<helper> vector_type;
+ typedef typename boost::range_iterator<vector_type const>::type vector_iterator_type;
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ boost::timer timer;
+#endif
+
+
+ std::size_t count_total = ring_map.size();
+ std::size_t count_positive = 0;
+ std::size_t index_positive = 0; // only used if count_positive>0
+ std::size_t index = 0;
+
+ // Copy to vector (with new approach this might be obsolete as well, using the map directly)
+ vector_type vector(count_total);
+
+ for (map_iterator_type it = boost::begin(ring_map);
+ it != boost::end(ring_map); ++it, ++index)
+ {
+ vector[index] = helper(it->first, it->second.get_area());
+ helper& item = vector[index];
+ switch(it->first.source_index)
+ {
+ case 0 :
+ geometry::envelope(get_ring<tag1>::apply(it->first, geometry1),
+ item.envelope);
+ break;
+ case 1 :
+ geometry::envelope(get_ring<tag2>::apply(it->first, geometry2),
+ item.envelope);
+ break;
+ case 2 :
+ geometry::envelope(get_ring<void>::apply(it->first, collection),
+ item.envelope);
+ break;
+ }
+ if (item.real_area > 0)
+ {
+ count_positive++;
+ index_positive = index;
+ }
+ }
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << " ap: created helper vector: " << timer.elapsed() << std::endl;
+#endif
+
+ if (! check_for_orientation)
+ {
+ if (count_positive == count_total)
+ {
+ // Optimization for only positive rings
+ // -> no assignment of parents or reversal necessary, ready here.
+ return;
+ }
+
+ if (count_positive == 1)
+ {
+ // Optimization for one outer ring
+ // -> assign this as parent to all others (all interior rings)
+ // In unions, this is probably the most occuring case and gives
+ // a dramatic improvement (factor 5 for star_comb testcase)
+ ring_identifier id_of_positive = vector[index_positive].id;
+ ring_info_type& outer = ring_map[id_of_positive];
+ std::size_t index = 0;
+ for (vector_iterator_type it = boost::begin(vector);
+ it != boost::end(vector); ++it, ++index)
+ {
+ if (index != index_positive)
+ {
+ ring_info_type& inner = ring_map[it->id];
+ inner.parent = id_of_positive;
+ outer.children.push_back(it->id);
+ }
+ }
+ return;
+ }
+ }
+
+ assign_visitor
+ <
+ Geometry1, Geometry2,
+ RingCollection, RingMap
+ > visitor(geometry1, geometry2, collection, ring_map, check_for_orientation);
+
+ geometry::partition
+ <
+ box_type, ring_info_helper_get_box, ring_info_helper_ovelaps_box
+ >::apply(vector, visitor);
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << " ap: quadradic loop: " << timer.elapsed() << std::endl;
+ std::cout << " ap: check_for_orientation " << check_for_orientation << std::endl;
+#endif
+ }
+
+ if (check_for_orientation)
+ {
+ for (map_iterator_type it = boost::begin(ring_map);
+ it != boost::end(ring_map); ++it)
+ {
+ if (geometry::math::equals(it->second.get_area(), 0))
+ {
+ it->second.discarded = true;
+ }
+ else if (it->second.parent.source_index >= 0 && it->second.get_area() > 0)
+ {
+ // Discard positive inner ring with parent
+ it->second.discarded = true;
+ it->second.parent.source_index = -1;
+ }
+ else if (it->second.parent.source_index < 0 && it->second.get_area() < 0)
+ {
+ // Reverse negative ring without parent
+ it->second.reversed = true;
+ }
+ }
+ }
+
+ // Assign childlist
+ for (map_iterator_type it = boost::begin(ring_map);
+ it != boost::end(ring_map); ++it)
+ {
+ if (it->second.parent.source_index >= 0)
+ {
+ ring_map[it->second.parent].children.push_back(it->first);
+ }
+ }
+}
+
+template
+<
+ typename Geometry,
+ typename RingCollection,
+ typename RingMap
+>
+inline void assign_parents(Geometry const& geometry,
+ RingCollection const& collection,
+ RingMap& ring_map,
+ bool check_for_orientation)
+{
+ // Call it with an empty geometry
+ // (ring_map should be empty for source_id==1)
+
+ Geometry empty;
+ assign_parents(geometry, empty, collection, ring_map, check_for_orientation);
+}
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ASSIGN_PARENTS_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp b/src/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp
new file mode 100644
index 0000000..012b3ac
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp
@@ -0,0 +1,170 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
+
+#include <cstddef>
+#include <string>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/has_self_intersections.hpp>
+#if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT)
+# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
+# include <boost/geometry/io/wkt/wkt.hpp>
+#endif
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+template <typename Turns>
+inline void clear_visit_info(Turns& turns)
+{
+ typedef typename boost::range_value<Turns>::type tp_type;
+
+ for (typename boost::range_iterator<Turns>::type
+ it = boost::begin(turns);
+ it != boost::end(turns);
+ ++it)
+ {
+ for (typename boost::range_iterator
+ <
+ typename tp_type::container_type
+ >::type op_it = boost::begin(it->operations);
+ op_it != boost::end(it->operations);
+ ++op_it)
+ {
+ op_it->visited.clear();
+ }
+ it->discarded = false;
+ }
+}
+
+struct backtrack_state
+{
+ bool m_good;
+
+ inline backtrack_state() : m_good(true) {}
+ inline void reset() { m_good = true; }
+ inline bool good() const { return m_good; }
+};
+
+
+template
+<
+ typename Geometry1,
+ typename Geometry2
+>
+class backtrack_check_self_intersections
+{
+ struct state : public backtrack_state
+ {
+ bool m_checked;
+ inline state()
+ : m_checked()
+ {}
+ };
+public :
+ typedef state state_type;
+
+ template <typename Operation, typename Rings, typename Turns>
+ static inline void apply(std::size_t size_at_start,
+ Rings& rings, typename boost::range_value<Rings>::type& ring,
+ Turns& turns, Operation& operation,
+ std::string const& ,
+ Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ state_type& state
+ )
+ {
+ state.m_good = false;
+
+ // Check self-intersections and throw exception if appropriate
+ if (! state.m_checked)
+ {
+ state.m_checked = true;
+ has_self_intersections(geometry1);
+ has_self_intersections(geometry2);
+ }
+
+ // Make bad output clean
+ rings.resize(size_at_start);
+ ring.clear();
+
+ // Reject this as a starting point
+ operation.visited.set_rejected();
+
+ // And clear all visit info
+ clear_visit_info(turns);
+ }
+};
+
+#ifdef BOOST_GEOMETRY_OVERLAY_REPORT_WKT
+template
+<
+ typename Geometry1,
+ typename Geometry2
+>
+class backtrack_debug
+{
+public :
+ typedef backtrack_state state_type;
+
+ template <typename Operation, typename Rings, typename Turns>
+ static inline void apply(std::size_t size_at_start,
+ Rings& rings, typename boost::range_value<Rings>::type& ring,
+ Turns& turns, Operation& operation,
+ std::string const& reason,
+ Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ state_type& state
+ )
+ {
+ std::cout << " REJECT " << reason << std::endl;
+
+ state.m_good = false;
+
+ rings.resize(size_at_start);
+ ring.clear();
+ operation.visited.set_rejected();
+ clear_visit_info(turns);
+
+ int c = 0;
+ for (int i = 0; i < turns.size(); i++)
+ {
+ for (int j = 0; j < 2; j++)
+ {
+ if (turns[i].operations[j].visited.rejected())
+ {
+ c++;
+ }
+ }
+ }
+ std::cout << "BACKTRACK (" << reason << " )"
+ << " " << c << " of " << turns.size() << " rejected"
+ << std::endl;
+ std::cout
+ << geometry::wkt(geometry1) << std::endl
+ << geometry::wkt(geometry2) << std::endl;
+ }
+};
+#endif // BOOST_GEOMETRY_OVERLAY_REPORT_WKT
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp b/src/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp
new file mode 100644
index 0000000..2003d23
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp
@@ -0,0 +1,64 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CALCULATE_DISTANCE_POLICY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CALCULATE_DISTANCE_POLICY_HPP
+
+
+#include <boost/geometry/algorithms/comparable_distance.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+/*!
+ \brief Policy calculating distance
+ \details get_turn_info has an optional policy to get some
+ extra information.
+ This policy calculates the distance (using default distance strategy)
+ */
+struct calculate_distance_policy
+{
+ static bool const include_no_turn = false;
+ static bool const include_degenerate = false;
+ static bool const include_opposite = false;
+
+ template
+ <
+ typename Info,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(Info& info, Point1 const& p1, Point2 const& p2,
+ IntersectionInfo const&, DirInfo const&)
+ {
+ info.operations[0].enriched.distance
+ = geometry::comparable_distance(info.point, p1);
+ info.operations[1].enriched.distance
+ = geometry::comparable_distance(info.point, p2);
+ }
+
+};
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CALCULATE_DISTANCE_POLICY_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/check_enrich.hpp b/src/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
new file mode 100644
index 0000000..b210fd0
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/check_enrich.hpp
@@ -0,0 +1,172 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
+
+
+#include <cstddef>
+
+
+#include <boost/assert.hpp>
+#include <boost/range.hpp>
+
+
+
+#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+template<typename Turn>
+struct meta_turn
+{
+ int index;
+ Turn const* turn;
+ bool handled[2];
+
+ inline meta_turn(int i, Turn const& t)
+ : index(i), turn(&t)
+ {
+ handled[0] = false;
+ handled[1] = false;
+ }
+};
+
+
+template <typename MetaTurn>
+inline void display(MetaTurn const& meta_turn, std::string const& reason = "")
+{
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << meta_turn.index
+ << "\tMethods: " << method_char(meta_turn.turn->method)
+ << " operations: " << operation_char(meta_turn.turn->operations[0].operation)
+ << operation_char(meta_turn.turn->operations[1].operation)
+ << " travels to " << meta_turn.turn->operations[0].enriched.travels_to_ip_index
+ << " and " << meta_turn.turn->operations[1].enriched.travels_to_ip_index
+ //<< " -> " << op_index
+ << " " << reason
+ << std::endl;
+#endif
+}
+
+
+template <typename MetaTurns, typename MetaTurn>
+inline void check_detailed(MetaTurns& meta_turns, MetaTurn const& meta_turn,
+ int op_index, int cycle, int start, operation_type for_operation,
+ bool& error)
+{
+ display(meta_turn);
+ int const ip_index = meta_turn.turn->operations[op_index].enriched.travels_to_ip_index;
+ if (ip_index >= 0)
+ {
+ bool found = false;
+
+ if (ip_index == start)
+ {
+ display(meta_turns[ip_index], " FINISH");
+ return;
+ }
+
+ // check on continuing, or on same-operation-on-same-geometry
+ if (! meta_turns[ip_index].handled[op_index]
+ && (meta_turns[ip_index].turn->operations[op_index].operation == operation_continue
+ || meta_turns[ip_index].turn->operations[op_index].operation == for_operation)
+ )
+ {
+ meta_turns[ip_index].handled[op_index] = true;
+ check_detailed(meta_turns, meta_turns[ip_index], op_index, cycle, start, for_operation, error);
+ found = true;
+ }
+ // check on other geometry
+ if (! found)
+ {
+ int const other_index = 1 - op_index;
+ if (! meta_turns[ip_index].handled[other_index]
+ && meta_turns[ip_index].turn->operations[other_index].operation == for_operation)
+ {
+ meta_turns[ip_index].handled[other_index] = true;
+ check_detailed(meta_turns, meta_turns[ip_index], other_index, cycle, start, for_operation, error);
+ found = true;
+ }
+ }
+
+ if (! found)
+ {
+ display(meta_turns[ip_index], " STOP");
+ error = true;
+#ifndef BOOST_GEOMETRY_DEBUG_ENRICH
+ //std::cout << " STOP";
+#endif
+ }
+ }
+}
+
+
+template <typename TurnPoints>
+inline bool check_graph(TurnPoints& turn_points, operation_type for_operation)
+{
+ typedef typename boost::range_value<TurnPoints>::type turn_point_type;
+
+ bool error = false;
+ int index = 0;
+
+ std::vector<meta_turn<turn_point_type> > meta_turns;
+ for (typename boost::range_iterator<TurnPoints const>::type
+ it = boost::begin(turn_points);
+ it != boost::end(turn_points);
+ ++it, ++index)
+ {
+ meta_turns.push_back(meta_turn<turn_point_type>(index, *it));
+ }
+
+ int cycle = 0;
+ for (typename boost::range_iterator<std::vector<meta_turn<turn_point_type> > > ::type
+ it = boost::begin(meta_turns);
+ it != boost::end(meta_turns);
+ ++it)
+ {
+ if (! (it->turn->blocked() || it->turn->is_discarded()))
+ {
+ for (int i = 0 ; i < 2; i++)
+ {
+ if (! it->handled[i]
+ && it->turn->operations[i].operation == for_operation)
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << "CYCLE " << cycle << std::endl;
+#endif
+ it->handled[i] = true;
+ check_detailed(meta_turns, *it, i, cycle++, it->index, for_operation, error);
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout <<" END CYCLE " << it->index << std::endl;
+#endif
+ }
+ }
+ }
+ }
+ return error;
+}
+
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp b/src/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
new file mode 100644
index 0000000..fc4f657
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp
@@ -0,0 +1,242 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLIP_LINESTRING_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLIP_LINESTRING_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace intersection
+{
+
+/*!
+ \brief Strategy: line clipping algorithm after Liang Barsky
+ \ingroup overlay
+ \details The Liang-Barsky line clipping algorithm clips a line with a clipping box.
+ It is slightly adapted in the sense that it returns which points are clipped
+ \tparam B input box type of clipping box
+ \tparam P input/output point-type of segments to be clipped
+ \note The algorithm is currently only implemented for 2D Cartesian points
+ \note Though it is implemented in namespace strategy, and theoretically another
+ strategy could be used, it is not (yet) updated to the general strategy concepts,
+ and not (yet) splitted into a file in folder strategies
+ \author Barend Gehrels, and the following recourses
+ - A tutorial: http://www.skytopia.com/project/articles/compsci/clipping.html
+ - a German applet (link broken): http://ls7-www.cs.uni-dortmund.de/students/projectgroups/acit/lineclip.shtml
+*/
+template<typename Box, typename Point>
+class liang_barsky
+{
+private:
+ typedef model::referring_segment<Point> segment_type;
+
+ template <typename T>
+ inline bool check_edge(T const& p, T const& q, T& t1, T& t2) const
+ {
+ bool visible = true;
+
+ if(p < 0)
+ {
+ T const r = q / p;
+ if (r > t2)
+ visible = false;
+ else if (r > t1)
+ t1 = r;
+ }
+ else if(p > 0)
+ {
+ T const r = q / p;
+ if (r < t1)
+ visible = false;
+ else if (r < t2)
+ t2 = r;
+ }
+ else
+ {
+ if (q < 0)
+ visible = false;
+ }
+
+ return visible;
+ }
+
+public:
+
+ inline bool clip_segment(Box const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
+ {
+ typedef typename select_coordinate_type<Box, Point>::type coordinate_type;
+
+ coordinate_type t1 = 0;
+ coordinate_type t2 = 1;
+
+ coordinate_type const dx = get<1, 0>(s) - get<0, 0>(s);
+ coordinate_type const dy = get<1, 1>(s) - get<0, 1>(s);
+
+ coordinate_type const p1 = -dx;
+ coordinate_type const p2 = dx;
+ coordinate_type const p3 = -dy;
+ coordinate_type const p4 = dy;
+
+ coordinate_type const q1 = get<0, 0>(s) - get<min_corner, 0>(b);
+ coordinate_type const q2 = get<max_corner, 0>(b) - get<0, 0>(s);
+ coordinate_type const q3 = get<0, 1>(s) - get<min_corner, 1>(b);
+ coordinate_type const q4 = get<max_corner, 1>(b) - get<0, 1>(s);
+
+ if (check_edge(p1, q1, t1, t2) // left
+ && check_edge(p2, q2, t1, t2) // right
+ && check_edge(p3, q3, t1, t2) // bottom
+ && check_edge(p4, q4, t1, t2)) // top
+ {
+ sp1_clipped = t1 > 0;
+ sp2_clipped = t2 < 1;
+
+ if (sp2_clipped)
+ {
+ set<1, 0>(s, get<0, 0>(s) + t2 * dx);
+ set<1, 1>(s, get<0, 1>(s) + t2 * dy);
+ }
+
+ if(sp1_clipped)
+ {
+ set<0, 0>(s, get<0, 0>(s) + t1 * dx);
+ set<0, 1>(s, get<0, 1>(s) + t1 * dy);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ template<typename Linestring, typename OutputIterator>
+ inline void apply(Linestring& line_out, OutputIterator out) const
+ {
+ if (!boost::empty(line_out))
+ {
+ *out = line_out;
+ ++out;
+ geometry::clear(line_out);
+ }
+ }
+};
+
+
+}} // namespace strategy::intersection
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection
+{
+
+/*!
+ \brief Clips a linestring with a box
+ \details A linestring is intersected (clipped) by the specified box
+ and the resulting linestring, or pieces of linestrings, are sent to the specified output operator.
+ \tparam OutputLinestring type of the output linestrings
+ \tparam OutputIterator an output iterator which outputs linestrings
+ \tparam Linestring linestring-type, for example a vector of points, matching the output-iterator type,
+ the points should also match the input-iterator type
+ \tparam Box box type
+ \tparam Strategy strategy, a clipping strategy which should implement the methods "clip_segment" and "apply"
+*/
+template
+<
+ typename OutputLinestring,
+ typename OutputIterator,
+ typename Range,
+ typename Box,
+ typename Strategy
+>
+OutputIterator clip_range_with_box(Box const& b, Range const& range,
+ OutputIterator out, Strategy const& strategy)
+{
+ if (boost::begin(range) == boost::end(range))
+ {
+ return out;
+ }
+
+ typedef typename point_type<OutputLinestring>::type point_type;
+
+ OutputLinestring line_out;
+
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+ iterator_type vertex = boost::begin(range);
+ for(iterator_type previous = vertex++;
+ vertex != boost::end(range);
+ ++previous, ++vertex)
+ {
+ point_type p1, p2;
+ geometry::convert(*previous, p1);
+ geometry::convert(*vertex, p2);
+
+ // Clip the segment. Five situations:
+ // 1. Segment is invisible, finish line if any (shouldn't occur)
+ // 2. Segment is completely visible. Add (p1)-p2 to line
+ // 3. Point 1 is invisible (clipped), point 2 is visible. Start new line from p1-p2...
+ // 4. Point 1 is visible, point 2 is invisible (clipped). End the line with ...p2
+ // 5. Point 1 and point 2 are both invisible (clipped). Start/finish an independant line p1-p2
+ //
+ // This results in:
+ // a. if p1 is clipped, start new line
+ // b. if segment is partly or completely visible, add the segment
+ // c. if p2 is clipped, end the line
+
+ bool c1 = false;
+ bool c2 = false;
+ model::referring_segment<point_type> s(p1, p2);
+
+ if (!strategy.clip_segment(b, s, c1, c2))
+ {
+ strategy.apply(line_out, out);
+ }
+ else
+ {
+ // a. If necessary, finish the line and add a start a new one
+ if (c1)
+ {
+ strategy.apply(line_out, out);
+ }
+
+ // b. Add p1 only if it is the first point, then add p2
+ if (boost::empty(line_out))
+ {
+ detail::overlay::append_no_duplicates(line_out, p1, true);
+ }
+ detail::overlay::append_no_duplicates(line_out, p2);
+
+ // c. If c2 is clipped, finish the line
+ if (c2)
+ {
+ strategy.apply(line_out, out);
+ }
+ }
+
+ }
+
+ // Add last part
+ strategy.apply(line_out, out);
+ return out;
+}
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CLIP_LINESTRING_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/convert_ring.hpp b/src/boost/geometry/algorithms/detail/overlay/convert_ring.hpp
new file mode 100644
index 0000000..05bd721
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/convert_ring.hpp
@@ -0,0 +1,99 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/range/algorithm/reverse.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+template<typename Tag>
+struct convert_ring
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TAG
+ , (types<Tag>)
+ );
+};
+
+template<>
+struct convert_ring<ring_tag>
+{
+ template<typename Destination, typename Source>
+ static inline void apply(Destination& destination, Source const& source,
+ bool append, bool reverse)
+ {
+ if (! append)
+ {
+ geometry::convert(source, destination);
+ if (reverse)
+ {
+ boost::reverse(destination);
+ }
+ }
+ }
+};
+
+
+template<>
+struct convert_ring<polygon_tag>
+{
+ template<typename Destination, typename Source>
+ static inline void apply(Destination& destination, Source const& source,
+ bool append, bool reverse)
+ {
+ if (! append)
+ {
+ geometry::convert(source, exterior_ring(destination));
+ if (reverse)
+ {
+ boost::reverse(exterior_ring(destination));
+ }
+ }
+ else
+ {
+ interior_rings(destination).resize(
+ interior_rings(destination).size() + 1);
+ geometry::convert(source, interior_rings(destination).back());
+ if (reverse)
+ {
+ boost::reverse(interior_rings(destination).back());
+ }
+ }
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp b/src/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
new file mode 100644
index 0000000..5e18d04
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp
@@ -0,0 +1,295 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
+
+
+#include <boost/array.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy_segments
+{
+
+
+template <typename Range, bool Reverse, typename SegmentIdentifier, typename PointOut>
+struct copy_segment_point_range
+{
+ typedef typename closeable_view
+ <
+ Range const,
+ closure<Range>::value
+ >::type cview_type;
+
+ typedef typename reversible_view
+ <
+ cview_type const,
+ Reverse ? iterate_reverse : iterate_forward
+ >::type rview_type;
+
+ static inline bool apply(Range const& range,
+ SegmentIdentifier const& seg_id, bool second,
+ PointOut& point)
+ {
+ int index = seg_id.segment_index;
+ if (second)
+ {
+ index++;
+ if (index >= int(boost::size(range)))
+ {
+ index = 0;
+ }
+ }
+
+ // Exception?
+ if (index >= int(boost::size(range)))
+ {
+ return false;
+ }
+
+ cview_type cview(range);
+ rview_type view(cview);
+
+
+ geometry::convert(*(boost::begin(view) + index), point);
+ return true;
+ }
+};
+
+
+template <typename Polygon, bool Reverse, typename SegmentIdentifier, typename PointOut>
+struct copy_segment_point_polygon
+{
+ static inline bool apply(Polygon const& polygon,
+ SegmentIdentifier const& seg_id, bool second,
+ PointOut& point)
+ {
+ // Call ring-version with the right ring
+ return copy_segment_point_range
+ <
+ typename geometry::ring_type<Polygon>::type,
+ Reverse,
+ SegmentIdentifier,
+ PointOut
+ >::apply
+ (
+ seg_id.ring_index < 0
+ ? geometry::exterior_ring(polygon)
+ : geometry::interior_rings(polygon)[seg_id.ring_index],
+ seg_id, second,
+ point
+ );
+ }
+};
+
+
+template <typename Box, bool Reverse, typename SegmentIdentifier, typename PointOut>
+struct copy_segment_point_box
+{
+ static inline bool apply(Box const& box,
+ SegmentIdentifier const& seg_id, bool second,
+ PointOut& point)
+ {
+ int index = seg_id.segment_index;
+ if (second)
+ {
+ index++;
+ }
+
+ boost::array<typename point_type<Box>::type, 4> bp;
+ assign_box_corners_oriented<Reverse>(box, bp);
+ point = bp[index % 4];
+ return true;
+ }
+};
+
+
+
+
+}} // namespace detail::copy_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename GeometryIn,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename PointOut
+>
+struct copy_segment_point
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<GeometryIn>)
+ );
+};
+
+
+template <typename LineString, bool Reverse, typename SegmentIdentifier, typename PointOut>
+struct copy_segment_point<linestring_tag, LineString, Reverse, SegmentIdentifier, PointOut>
+ : detail::copy_segments::copy_segment_point_range
+ <
+ LineString, Reverse, SegmentIdentifier, PointOut
+ >
+{};
+
+
+template <typename Ring, bool Reverse, typename SegmentIdentifier, typename PointOut>
+struct copy_segment_point<ring_tag, Ring, Reverse, SegmentIdentifier, PointOut>
+ : detail::copy_segments::copy_segment_point_range
+ <
+ Ring, Reverse, SegmentIdentifier, PointOut
+ >
+{};
+
+template <typename Polygon, bool Reverse, typename SegmentIdentifier, typename PointOut>
+struct copy_segment_point<polygon_tag, Polygon, Reverse, SegmentIdentifier, PointOut>
+ : detail::copy_segments::copy_segment_point_polygon
+ <
+ Polygon, Reverse, SegmentIdentifier, PointOut
+ >
+{};
+
+
+template <typename Box, bool Reverse, typename SegmentIdentifier, typename PointOut>
+struct copy_segment_point<box_tag, Box, Reverse, SegmentIdentifier, PointOut>
+ : detail::copy_segments::copy_segment_point_box
+ <
+ Box, Reverse, SegmentIdentifier, PointOut
+ >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+
+
+/*!
+ \brief Helper function, copies a point from a segment
+ \ingroup overlay
+ */
+template<bool Reverse, typename Geometry, typename SegmentIdentifier, typename PointOut>
+inline bool copy_segment_point(Geometry const& geometry,
+ SegmentIdentifier const& seg_id, bool second,
+ PointOut& point_out)
+{
+ concept::check<Geometry const>();
+
+ return dispatch::copy_segment_point
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Reverse,
+ SegmentIdentifier,
+ PointOut
+ >::apply(geometry, seg_id, second, point_out);
+}
+
+
+/*!
+ \brief Helper function, to avoid the same construct several times,
+ copies a point, based on a source-index and two geometries
+ \ingroup overlay
+ */
+template
+<
+ bool Reverse1, bool Reverse2,
+ typename Geometry1, typename Geometry2,
+ typename SegmentIdentifier,
+ typename PointOut
+>
+inline bool copy_segment_point(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ SegmentIdentifier const& seg_id, bool second,
+ PointOut& point_out)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ if (seg_id.source_index == 0)
+ {
+ return dispatch::copy_segment_point
+ <
+ typename tag<Geometry1>::type,
+ Geometry1,
+ Reverse1,
+ SegmentIdentifier,
+ PointOut
+ >::apply(geometry1, seg_id, second, point_out);
+ }
+ else if (seg_id.source_index == 1)
+ {
+ return dispatch::copy_segment_point
+ <
+ typename tag<Geometry2>::type,
+ Geometry2,
+ Reverse2,
+ SegmentIdentifier,
+ PointOut
+ >::apply(geometry2, seg_id, second, point_out);
+ }
+ // Exception?
+ return false;
+}
+
+
+/*!
+ \brief Helper function, to avoid the same construct several times,
+ copies a point, based on a source-index and two geometries
+ \ingroup overlay
+ */
+template
+<
+ bool Reverse1, bool Reverse2,
+ typename Geometry1, typename Geometry2,
+ typename SegmentIdentifier,
+ typename PointOut
+>
+inline bool copy_segment_points(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ SegmentIdentifier const& seg_id,
+ PointOut& point1, PointOut& point2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ return copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, false, point1)
+ && copy_segment_point<Reverse1, Reverse2>(geometry1, geometry2, seg_id, true, point2);
+}
+
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/src/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
new file mode 100644
index 0000000..805f392
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/copy_segments.hpp
@@ -0,0 +1,328 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
+
+
+#include <boost/array.hpp>
+#include <boost/mpl/assert.hpp>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/iterators/ever_circling_iterator.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy_segments
+{
+
+
+template
+<
+ typename Ring,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments_ring
+{
+ typedef typename closeable_view
+ <
+ Ring const,
+ closure<Ring>::value
+ >::type cview_type;
+
+ typedef typename reversible_view
+ <
+ cview_type const,
+ Reverse ? iterate_reverse : iterate_forward
+ >::type rview_type;
+
+ typedef typename boost::range_iterator<rview_type const>::type iterator;
+ typedef geometry::ever_circling_iterator<iterator> ec_iterator;
+
+ static inline void apply(Ring const& ring,
+ SegmentIdentifier const& seg_id, int to_index,
+ RangeOut& current_output)
+ {
+ cview_type cview(ring);
+ rview_type view(cview);
+
+ // The problem: sometimes we want to from "3" to "2"
+ // -> end = "3" -> end == begin
+ // This is not convenient with iterators.
+
+ // So we use the ever-circling iterator and determine when to step out
+
+ int const from_index = seg_id.segment_index + 1;
+
+ // Sanity check
+ BOOST_ASSERT(from_index < int(boost::size(view)));
+
+ ec_iterator it(boost::begin(view), boost::end(view),
+ boost::begin(view) + from_index);
+
+ // [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK
+ // [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK
+ // [1..1], travel the whole ring round
+ typedef typename boost::range_difference<Ring>::type size_type;
+ size_type const count = from_index <= to_index
+ ? to_index - from_index + 1
+ : int(boost::size(view)) - from_index + to_index + 1;
+
+ for (size_type i = 0; i < count; ++i, ++it)
+ {
+ detail::overlay::append_no_duplicates(current_output, *it);
+ }
+ }
+};
+
+template
+<
+ typename LineString,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments_linestring
+{
+
+ typedef typename boost::range_iterator<LineString const>::type iterator;
+
+ static inline void apply(LineString const& ls,
+ SegmentIdentifier const& seg_id, int to_index,
+ RangeOut& current_output)
+ {
+ int const from_index = seg_id.segment_index + 1;
+
+ // Sanity check
+ if (from_index > to_index || from_index < 0 || to_index >= int(boost::size(ls)))
+ {
+ return;
+ }
+
+ typedef typename boost::range_difference<LineString>::type size_type;
+ size_type const count = to_index - from_index + 1;
+
+ typename boost::range_iterator<LineString const>::type it = boost::begin(ls) + from_index;
+
+ for (size_type i = 0; i < count; ++i, ++it)
+ {
+ detail::overlay::append_no_duplicates(current_output, *it);
+ }
+ }
+};
+
+template
+<
+ typename Polygon,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments_polygon
+{
+ static inline void apply(Polygon const& polygon,
+ SegmentIdentifier const& seg_id, int to_index,
+ RangeOut& current_output)
+ {
+ // Call ring-version with the right ring
+ copy_segments_ring
+ <
+ typename geometry::ring_type<Polygon>::type,
+ Reverse,
+ SegmentIdentifier,
+ RangeOut
+ >::apply
+ (
+ seg_id.ring_index < 0
+ ? geometry::exterior_ring(polygon)
+ : geometry::interior_rings(polygon)[seg_id.ring_index],
+ seg_id, to_index,
+ current_output
+ );
+ }
+};
+
+
+template
+<
+ typename Box,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments_box
+{
+ static inline void apply(Box const& box,
+ SegmentIdentifier const& seg_id, int to_index,
+ RangeOut& current_output)
+ {
+ int index = seg_id.segment_index + 1;
+ BOOST_ASSERT(index < 5);
+
+ int const count = index <= to_index
+ ? to_index - index + 1
+ : 5 - index + to_index + 1;
+
+ // Create array of points, the fifth one closes it
+ boost::array<typename point_type<Box>::type, 5> bp;
+ assign_box_corners_oriented<Reverse>(box, bp);
+ bp[4] = bp[0];
+
+ // (possibly cyclic) copy to output
+ // (see comments in ring-version)
+ for (int i = 0; i < count; i++, index++)
+ {
+ detail::overlay::append_no_duplicates(current_output, bp[index % 5]);
+
+ }
+ }
+};
+
+
+}} // namespace detail::copy_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag,
+ typename GeometryIn,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<GeometryIn>)
+ );
+};
+
+
+template
+<
+ typename Ring,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments<ring_tag, Ring, Reverse, SegmentIdentifier, RangeOut>
+ : detail::copy_segments::copy_segments_ring
+ <
+ Ring, Reverse, SegmentIdentifier, RangeOut
+ >
+{};
+
+
+
+template
+<
+ typename LineString,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments<linestring_tag, LineString, Reverse, SegmentIdentifier, RangeOut>
+ : detail::copy_segments::copy_segments_linestring
+ <
+ LineString, Reverse, SegmentIdentifier, RangeOut
+ >
+{};
+
+template
+<
+ typename Polygon,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments<polygon_tag, Polygon, Reverse, SegmentIdentifier, RangeOut>
+ : detail::copy_segments::copy_segments_polygon
+ <
+ Polygon, Reverse, SegmentIdentifier, RangeOut
+ >
+{};
+
+
+template
+<
+ typename Box,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments<box_tag, Box, Reverse, SegmentIdentifier, RangeOut>
+ : detail::copy_segments::copy_segments_box
+ <
+ Box, Reverse, SegmentIdentifier, RangeOut
+ >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Copy segments from a geometry, starting with the specified segment (seg_id)
+ until the specified index (to_index)
+ \ingroup overlay
+ */
+template
+<
+ bool Reverse,
+ typename Geometry,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+inline void copy_segments(Geometry const& geometry,
+ SegmentIdentifier const& seg_id, int to_index,
+ RangeOut& range_out)
+{
+ concept::check<Geometry const>();
+
+ dispatch::copy_segments
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Reverse,
+ SegmentIdentifier,
+ RangeOut
+ >::apply(geometry, seg_id, to_index, range_out);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp b/src/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp
new file mode 100644
index 0000000..0cc3425
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp
@@ -0,0 +1,66 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DEBUG_TURN_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DEBUG_TURN_INFO_HPP
+
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/visit_info.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+inline char method_char(detail::overlay::method_type const& method)
+{
+ using namespace detail::overlay;
+ switch(method)
+ {
+ case method_none : return '-';
+ case method_disjoint : return 'd';
+ case method_crosses : return 'i';
+ case method_touch : return 't';
+ case method_touch_interior : return 'm';
+ case method_collinear : return 'c';
+ case method_equal : return 'e';
+ case method_error : return '!';
+ default : return '?';
+ }
+}
+
+inline char operation_char(detail::overlay::operation_type const& operation)
+{
+ using namespace detail::overlay;
+ switch(operation)
+ {
+ case operation_none : return '-';
+ case operation_union : return 'u';
+ case operation_intersection : return 'i';
+ case operation_blocked : return 'x';
+ case operation_continue : return 'c';
+ case operation_opposite : return 'o';
+ default : return '?';
+ }
+}
+
+inline char visited_char(detail::overlay::visit_info const& v)
+{
+ if (v.rejected()) return 'R';
+ if (v.started()) return 's';
+ if (v.visited()) return 'v';
+ if (v.none()) return '-';
+ if (v.finished()) return 'f';
+ return '?';
+}
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DEBUG_TURN_INFO_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/src/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
new file mode 100644
index 0000000..e4842d3
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp
@@ -0,0 +1,523 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICH_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICH_HPP
+
+#include <cstddef>
+#include <algorithm>
+#include <map>
+#include <set>
+#include <vector>
+
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+# include <iostream>
+# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
+# include <boost/geometry/io/wkt/wkt.hpp>
+# define BOOST_GEOMETRY_DEBUG_IDENTIFIER
+#endif
+
+#include <boost/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_relative_order.hpp>
+#include <boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp>
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+# include <boost/geometry/algorithms/detail/overlay/check_enrich.hpp>
+#endif
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+// Wraps "turn_operation" from turn_info.hpp,
+// giving it extra information
+template <typename TurnOperation>
+struct indexed_turn_operation
+{
+ typedef TurnOperation type;
+
+ int index;
+ int operation_index;
+ bool discarded;
+ TurnOperation subject;
+
+ inline indexed_turn_operation(int i, int oi, TurnOperation const& s)
+ : index(i)
+ , operation_index(oi)
+ , discarded(false)
+ , subject(s)
+ {}
+};
+
+template <typename IndexedTurnOperation>
+struct remove_discarded
+{
+ inline bool operator()(IndexedTurnOperation const& operation) const
+ {
+ return operation.discarded;
+ }
+};
+
+
+template
+<
+ typename TurnPoints,
+ typename Indexed,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2,
+ typename Strategy
+>
+struct sort_on_segment_and_distance
+{
+ inline sort_on_segment_and_distance(TurnPoints const& turn_points
+ , Geometry1 const& geometry1
+ , Geometry2 const& geometry2
+ , Strategy const& strategy
+ , bool* clustered)
+ : m_turn_points(turn_points)
+ , m_geometry1(geometry1)
+ , m_geometry2(geometry2)
+ , m_strategy(strategy)
+ , m_clustered(clustered)
+ {
+ }
+
+private :
+
+ TurnPoints const& m_turn_points;
+ Geometry1 const& m_geometry1;
+ Geometry2 const& m_geometry2;
+ Strategy const& m_strategy;
+ mutable bool* m_clustered;
+
+ inline bool consider_relative_order(Indexed const& left,
+ Indexed const& right) const
+ {
+ typedef typename geometry::point_type<Geometry1>::type point_type;
+ point_type pi, pj, ri, rj, si, sj;
+
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ left.subject.seg_id,
+ pi, pj);
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ left.subject.other_id,
+ ri, rj);
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ right.subject.other_id,
+ si, sj);
+
+ int const order = get_relative_order
+ <
+ point_type
+ >::apply(pi, pj,ri, rj, si, sj);
+ //debug("r/o", order == -1);
+ return order == -1;
+ }
+
+public :
+
+ // Note that left/right do NOT correspond to m_geometry1/m_geometry2
+ // but to the "indexed_turn_operation"
+ inline bool operator()(Indexed const& left, Indexed const& right) const
+ {
+ segment_identifier const& sl = left.subject.seg_id;
+ segment_identifier const& sr = right.subject.seg_id;
+
+ if (sl == sr
+ && geometry::math::equals(left.subject.enriched.distance
+ , right.subject.enriched.distance))
+ {
+ // Both left and right are located on the SAME segment.
+
+ // First check "real" intersection (crosses)
+ // -> distance zero due to precision, solve it by sorting
+ if (m_turn_points[left.index].method == method_crosses
+ && m_turn_points[right.index].method == method_crosses)
+ {
+ return consider_relative_order(left, right);
+ }
+
+ // If that is not the case, cluster it later on.
+ // Indicate that this is necessary.
+ *m_clustered = true;
+
+ return left.index < right.index;
+ }
+ return sl == sr
+ ? left.subject.enriched.distance < right.subject.enriched.distance
+ : sl < sr;
+
+ }
+};
+
+
+template<typename Turns, typename Operations>
+inline void update_discarded(Turns& turn_points, Operations& operations)
+{
+ // Vice-versa, set discarded to true for discarded operations;
+ // AND set discarded points to true
+ for (typename boost::range_iterator<Operations>::type it = boost::begin(operations);
+ it != boost::end(operations);
+ ++it)
+ {
+ if (turn_points[it->index].discarded)
+ {
+ it->discarded = true;
+ }
+ else if (it->discarded)
+ {
+ turn_points[it->index].discarded = true;
+ }
+ }
+}
+
+
+// Sorts IP-s of this ring on segment-identifier, and if on same segment,
+// on distance.
+// Then assigns for each IP which is the next IP on this segment,
+// plus the vertex-index to travel to, plus the next IP
+// (might be on another segment)
+template
+<
+ typename IndexType,
+ bool Reverse1, bool Reverse2,
+ typename Container,
+ typename TurnPoints,
+ typename Geometry1, typename Geometry2,
+ typename Strategy
+>
+inline void enrich_sort(Container& operations,
+ TurnPoints& turn_points,
+ operation_type for_operation,
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ typedef typename IndexType::type operations_type;
+
+ bool clustered = false;
+ std::sort(boost::begin(operations),
+ boost::end(operations),
+ sort_on_segment_and_distance
+ <
+ TurnPoints,
+ IndexType,
+ Geometry1, Geometry2,
+ Reverse1, Reverse2,
+ Strategy
+ >(turn_points, geometry1, geometry2, strategy, &clustered));
+
+ // DONT'T discard xx / (for union) ix / ii / (for intersection) ux / uu here
+ // It would give way to "lonely" ui turn points, traveling all
+ // the way round. See #105
+
+ if (clustered)
+ {
+ typedef typename boost::range_iterator<Container>::type nc_iterator;
+ nc_iterator it = boost::begin(operations);
+ nc_iterator begin_cluster = boost::end(operations);
+ for (nc_iterator prev = it++;
+ it != boost::end(operations);
+ prev = it++)
+ {
+ operations_type& prev_op = turn_points[prev->index]
+ .operations[prev->operation_index];
+ operations_type& op = turn_points[it->index]
+ .operations[it->operation_index];
+
+ if (prev_op.seg_id == op.seg_id
+ && (turn_points[prev->index].method != method_crosses
+ || turn_points[it->index].method != method_crosses)
+ && geometry::math::equals(prev_op.enriched.distance,
+ op.enriched.distance))
+ {
+ if (begin_cluster == boost::end(operations))
+ {
+ begin_cluster = prev;
+ }
+ }
+ else if (begin_cluster != boost::end(operations))
+ {
+ handle_cluster<IndexType, Reverse1, Reverse2>(begin_cluster, it, turn_points,
+ for_operation, geometry1, geometry2, strategy);
+ begin_cluster = boost::end(operations);
+ }
+ }
+ if (begin_cluster != boost::end(operations))
+ {
+ handle_cluster<IndexType, Reverse1, Reverse2>(begin_cluster, it, turn_points,
+ for_operation, geometry1, geometry2, strategy);
+ }
+ }
+
+ update_discarded(turn_points, operations);
+}
+
+
+template
+<
+ typename IndexType,
+ typename Container,
+ typename TurnPoints
+>
+inline void enrich_discard(Container& operations, TurnPoints& turn_points)
+{
+ update_discarded(turn_points, operations);
+
+ // Then delete discarded operations from vector
+ remove_discarded<IndexType> predicate;
+ operations.erase(
+ std::remove_if(boost::begin(operations),
+ boost::end(operations),
+ predicate),
+ boost::end(operations));
+}
+
+template
+<
+ typename IndexType,
+ typename Container,
+ typename TurnPoints,
+ typename Geometry1,
+ typename Geometry2,
+ typename Strategy
+>
+inline void enrich_assign(Container& operations,
+ TurnPoints& turn_points,
+ operation_type ,
+ Geometry1 const& , Geometry2 const& ,
+ Strategy const& )
+{
+ typedef typename IndexType::type operations_type;
+ typedef typename boost::range_iterator<Container const>::type iterator_type;
+
+
+ if (operations.size() > 0)
+ {
+ // Assign travel-to-vertex/ip index for each turning point.
+ // Because IP's are circular, PREV starts at the very last one,
+ // being assigned from the first one.
+ // "next ip on same segment" should not be considered circular.
+ bool first = true;
+ iterator_type it = boost::begin(operations);
+ for (iterator_type prev = it + (boost::size(operations) - 1);
+ it != boost::end(operations);
+ prev = it++)
+ {
+ operations_type& prev_op
+ = turn_points[prev->index].operations[prev->operation_index];
+ operations_type& op
+ = turn_points[it->index].operations[it->operation_index];
+
+ prev_op.enriched.travels_to_ip_index
+ = it->index;
+ prev_op.enriched.travels_to_vertex_index
+ = it->subject.seg_id.segment_index;
+
+ if (! first
+ && prev_op.seg_id.segment_index == op.seg_id.segment_index)
+ {
+ prev_op.enriched.next_ip_index = it->index;
+ }
+ first = false;
+ }
+ }
+
+ // DEBUG
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ {
+ for (iterator_type it = boost::begin(operations);
+ it != boost::end(operations);
+ ++it)
+ {
+ operations_type& op = turn_points[it->index]
+ .operations[it->operation_index];
+
+ std::cout << it->index
+ << " meth: " << method_char(turn_points[it->index].method)
+ << " seg: " << op.seg_id
+ << " dst: " << boost::numeric_cast<double>(op.enriched.distance)
+ << " op: " << operation_char(turn_points[it->index].operations[0].operation)
+ << operation_char(turn_points[it->index].operations[1].operation)
+ << " dsc: " << (turn_points[it->index].discarded ? "T" : "F")
+ << " ->vtx " << op.enriched.travels_to_vertex_index
+ << " ->ip " << op.enriched.travels_to_ip_index
+ << " ->nxt ip " << op.enriched.next_ip_index
+ //<< " vis: " << visited_char(op.visited)
+ << std::endl;
+ ;
+ }
+ }
+#endif
+ // END DEBUG
+
+}
+
+
+template <typename IndexedType, typename TurnPoints, typename MappedVector>
+inline void create_map(TurnPoints const& turn_points, MappedVector& mapped_vector)
+{
+ typedef typename boost::range_value<TurnPoints>::type turn_point_type;
+ typedef typename turn_point_type::container_type container_type;
+
+ int index = 0;
+ for (typename boost::range_iterator<TurnPoints const>::type
+ it = boost::begin(turn_points);
+ it != boost::end(turn_points);
+ ++it, ++index)
+ {
+ // Add operations on this ring, but skip discarded ones
+ if (! it->discarded)
+ {
+ int op_index = 0;
+ for (typename boost::range_iterator<container_type const>::type
+ op_it = boost::begin(it->operations);
+ op_it != boost::end(it->operations);
+ ++op_it, ++op_index)
+ {
+ // We should NOT skip blocked operations here
+ // because they can be relevant for "the other side"
+ // NOT if (op_it->operation != operation_blocked)
+
+ ring_identifier ring_id
+ (
+ op_it->seg_id.source_index,
+ op_it->seg_id.multi_index,
+ op_it->seg_id.ring_index
+ );
+ mapped_vector[ring_id].push_back
+ (
+ IndexedType(index, op_index, *op_it)
+ );
+ }
+ }
+ }
+}
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+
+/*!
+\brief All intersection points are enriched with successor information
+\ingroup overlay
+\tparam TurnPoints type of intersection container
+ (e.g. vector of "intersection/turn point"'s)
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Strategy side strategy type
+\param turn_points container containing intersectionpoints
+\param for_operation operation_type (union or intersection)
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy strategy
+ */
+template
+<
+ bool Reverse1, bool Reverse2,
+ typename TurnPoints,
+ typename Geometry1, typename Geometry2,
+ typename Strategy
+>
+inline void enrich_intersection_points(TurnPoints& turn_points,
+ detail::overlay::operation_type for_operation,
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ typedef typename boost::range_value<TurnPoints>::type turn_point_type;
+ typedef typename turn_point_type::turn_operation_type turn_operation_type;
+ typedef detail::overlay::indexed_turn_operation
+ <
+ turn_operation_type
+ > indexed_turn_operation;
+
+ typedef std::map
+ <
+ ring_identifier,
+ std::vector<indexed_turn_operation>
+ > mapped_vector_type;
+
+ // DISCARD ALL UU
+ // #76 is the reason that this is necessary...
+ // With uu, at all points there is the risk that rings are being traversed twice or more.
+ // Without uu, all rings having only uu will be untouched and gathered by assemble
+ for (typename boost::range_iterator<TurnPoints>::type
+ it = boost::begin(turn_points);
+ it != boost::end(turn_points);
+ ++it)
+ {
+ if (it->both(detail::overlay::operation_union))
+ {
+ it->discarded = true;
+ }
+ }
+
+
+ // Create a map of vectors of indexed operation-types to be able
+ // to sort intersection points PER RING
+ mapped_vector_type mapped_vector;
+
+ detail::overlay::create_map<indexed_turn_operation>(turn_points, mapped_vector);
+
+
+ // No const-iterator; contents of mapped copy is temporary,
+ // and changed by enrich
+ for (typename mapped_vector_type::iterator mit
+ = mapped_vector.begin();
+ mit != mapped_vector.end();
+ ++mit)
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << "ENRICH-sort Ring "
+ << mit->first << std::endl;
+#endif
+ detail::overlay::enrich_sort<indexed_turn_operation, Reverse1, Reverse2>(mit->second, turn_points, for_operation,
+ geometry1, geometry2, strategy);
+ }
+
+ for (typename mapped_vector_type::iterator mit
+ = mapped_vector.begin();
+ mit != mapped_vector.end();
+ ++mit)
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << "ENRICH-discard Ring "
+ << mit->first << std::endl;
+#endif
+ detail::overlay::enrich_discard<indexed_turn_operation>(mit->second, turn_points);
+ }
+
+ for (typename mapped_vector_type::iterator mit
+ = mapped_vector.begin();
+ mit != mapped_vector.end();
+ ++mit)
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << "ENRICH-assign Ring "
+ << mit->first << std::endl;
+#endif
+ detail::overlay::enrich_assign<indexed_turn_operation>(mit->second, turn_points, for_operation,
+ geometry1, geometry2, strategy);
+ }
+
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ //detail::overlay::check_graph(turn_points, for_operation);
+#endif
+
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICH_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp b/src/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
new file mode 100644
index 0000000..8c8ed96
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
@@ -0,0 +1,76 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICHMENT_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICHMENT_INFO_HPP
+
+
+#include <boost/geometry/strategies/distance.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+/*!
+\brief Keeps info to enrich intersection info (per source)
+\details Class to keep information necessary for traversal phase (a phase
+ of the overlay process). The information is gathered during the
+ enrichment phase
+ */
+template<typename P>
+struct enrichment_info
+{
+ typedef typename strategy::distance::services::return_type
+ <
+ typename strategy::distance::services::comparable_type
+ <
+ typename strategy::distance::services::default_strategy
+ <
+ point_tag,
+ P
+ >::type
+ >::type
+ >::type distance_type;
+
+ inline enrichment_info()
+ : travels_to_vertex_index(-1)
+ , travels_to_ip_index(-1)
+ , next_ip_index(-1)
+ , distance(distance_type())
+ {}
+
+ // vertex to which is free travel after this IP,
+ // so from "segment_index+1" to "travels_to_vertex_index", without IP-s,
+ // can be -1
+ int travels_to_vertex_index;
+
+ // same but now IP index, so "next IP index" but not on THIS segment
+ int travels_to_ip_index;
+
+ // index of next IP on this segment, -1 if there is no one
+ int next_ip_index;
+
+ distance_type distance; // distance-measurement from segment.first to IP
+};
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ENRICHMENT_INFO_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/follow.hpp b/src/boost/geometry/algorithms/detail/overlay/follow.hpp
new file mode 100644
index 0000000..b110cc9
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/follow.hpp
@@ -0,0 +1,416 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_FOLLOW_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_FOLLOW_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+#include <boost/mpl/assert.hpp>
+
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
+#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+
+#include <boost/geometry/algorithms/covered_by.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+namespace following
+{
+
+template <typename Turn, typename Operation>
+static inline bool is_entering(Turn const& /* TODO remove this parameter */, Operation const& op)
+{
+ // (Blocked means: blocked for polygon/polygon intersection, because
+ // they are reversed. But for polygon/line it is similar to continue)
+ return op.operation == operation_intersection
+ || op.operation == operation_continue
+ || op.operation == operation_blocked
+ ;
+}
+
+template
+<
+ typename Turn,
+ typename Operation,
+ typename LineString,
+ typename Polygon
+>
+static inline bool last_covered_by(Turn const& turn, Operation const& op,
+ LineString const& linestring, Polygon const& polygon)
+{
+ // Check any point between the this one and the first IP
+ typedef typename geometry::point_type<LineString>::type point_type;
+ point_type point_in_between;
+ detail::point_on_border::midpoint_helper
+ <
+ point_type,
+ 0, dimension<point_type>::value
+ >::apply(point_in_between, linestring[op.seg_id.segment_index], turn.point);
+
+ return geometry::covered_by(point_in_between, polygon);
+}
+
+
+template
+<
+ typename Turn,
+ typename Operation,
+ typename LineString,
+ typename Polygon
+>
+static inline bool is_leaving(Turn const& turn, Operation const& op,
+ bool entered, bool first,
+ LineString const& linestring, Polygon const& polygon)
+{
+ if (op.operation == operation_union)
+ {
+ return entered
+ || turn.method == method_crosses
+ || (first && last_covered_by(turn, op, linestring, polygon))
+ ;
+ }
+ return false;
+}
+
+
+template
+<
+ typename Turn,
+ typename Operation,
+ typename LineString,
+ typename Polygon
+>
+static inline bool is_staying_inside(Turn const& turn, Operation const& op,
+ bool entered, bool first,
+ LineString const& linestring, Polygon const& polygon)
+{
+ if (turn.method == method_crosses)
+ {
+ // The normal case, this is completely covered with entering/leaving
+ // so stay out of this time consuming "covered_by"
+ return false;
+ }
+
+ if (is_entering(turn, op))
+ {
+ return entered || (first && last_covered_by(turn, op, linestring, polygon));
+ }
+
+ return false;
+}
+
+template
+<
+ typename Turn,
+ typename Operation,
+ typename Linestring,
+ typename Polygon
+>
+static inline bool was_entered(Turn const& turn, Operation const& op, bool first,
+ Linestring const& linestring, Polygon const& polygon)
+{
+ if (first && (turn.method == method_collinear || turn.method == method_equal))
+ {
+ return last_covered_by(turn, op, linestring, polygon);
+ }
+ return false;
+}
+
+
+// Template specialization structure to call the right actions for the right type
+template<overlay_type OverlayType>
+struct action_selector
+{
+ // If you get here the overlay type is not intersection or difference
+ // BOOST_MPL_ASSERT(false);
+};
+
+// Specialization for intersection, containing the implementation
+template<>
+struct action_selector<overlay_intersection>
+{
+ template
+ <
+ typename OutputIterator,
+ typename LineStringOut,
+ typename LineString,
+ typename Point,
+ typename Operation
+ >
+ static inline void enter(LineStringOut& current_piece,
+ LineString const& ,
+ segment_identifier& segment_id,
+ int , Point const& point,
+ Operation const& operation, OutputIterator& )
+ {
+ // On enter, append the intersection point and remember starting point
+ detail::overlay::append_no_duplicates(current_piece, point);
+ segment_id = operation.seg_id;
+ }
+
+ template
+ <
+ typename OutputIterator,
+ typename LineStringOut,
+ typename LineString,
+ typename Point,
+ typename Operation
+ >
+ static inline void leave(LineStringOut& current_piece,
+ LineString const& linestring,
+ segment_identifier& segment_id,
+ int index, Point const& point,
+ Operation const& , OutputIterator& out)
+ {
+ // On leave, copy all segments from starting point, append the intersection point
+ // and add the output piece
+ geometry::copy_segments<false>(linestring, segment_id, index, current_piece);
+ detail::overlay::append_no_duplicates(current_piece, point);
+ if (current_piece.size() > 1)
+ {
+ *out++ = current_piece;
+ }
+ current_piece.clear();
+ }
+
+ static inline bool is_entered(bool entered)
+ {
+ return entered;
+ }
+
+ template <typename Point, typename Geometry>
+ static inline bool included(Point const& point, Geometry const& geometry)
+ {
+ return geometry::covered_by(point, geometry);
+ }
+
+};
+
+// Specialization for difference, which reverses these actions
+template<>
+struct action_selector<overlay_difference>
+{
+ typedef action_selector<overlay_intersection> normal_action;
+
+ template
+ <
+ typename OutputIterator,
+ typename LineStringOut,
+ typename LineString,
+ typename Point,
+ typename Operation
+ >
+ static inline void enter(LineStringOut& current_piece,
+ LineString const& linestring,
+ segment_identifier& segment_id,
+ int index, Point const& point,
+ Operation const& operation, OutputIterator& out)
+ {
+ normal_action::leave(current_piece, linestring, segment_id, index,
+ point, operation, out);
+ }
+
+ template
+ <
+ typename OutputIterator,
+ typename LineStringOut,
+ typename LineString,
+ typename Point,
+ typename Operation
+ >
+ static inline void leave(LineStringOut& current_piece,
+ LineString const& linestring,
+ segment_identifier& segment_id,
+ int index, Point const& point,
+ Operation const& operation, OutputIterator& out)
+ {
+ normal_action::enter(current_piece, linestring, segment_id, index,
+ point, operation, out);
+ }
+
+ static inline bool is_entered(bool entered)
+ {
+ return ! normal_action::is_entered(entered);
+ }
+
+ template <typename Point, typename Geometry>
+ static inline bool included(Point const& point, Geometry const& geometry)
+ {
+ return ! normal_action::included(point, geometry);
+ }
+
+};
+
+}
+
+/*!
+\brief Follows a linestring from intersection point to intersection point, outputting which
+ is inside, or outside, a ring or polygon
+\ingroup overlay
+ */
+template
+<
+ typename LineStringOut,
+ typename LineString,
+ typename Polygon,
+ overlay_type OverlayType
+>
+class follow
+{
+
+ template<typename Turn>
+ struct sort_on_segment
+ {
+ // In case of turn point at the same location, we want to have continue/blocked LAST
+ // because that should be followed (intersection) or skipped (difference).
+ inline int operation_order(Turn const& turn) const
+ {
+ operation_type const& operation = turn.operations[0].operation;
+ switch(operation)
+ {
+ case operation_opposite : return 0;
+ case operation_none : return 0;
+ case operation_union : return 1;
+ case operation_intersection : return 2;
+ case operation_blocked : return 3;
+ case operation_continue : return 4;
+ }
+ return -1;
+ };
+
+ inline bool use_operation(Turn const& left, Turn const& right) const
+ {
+ // If they are the same, OK.
+ return operation_order(left) < operation_order(right);
+ }
+
+ inline bool use_distance(Turn const& left, Turn const& right) const
+ {
+ return geometry::math::equals(left.operations[0].enriched.distance, right.operations[0].enriched.distance)
+ ? use_operation(left, right)
+ : left.operations[0].enriched.distance < right.operations[0].enriched.distance
+ ;
+ }
+
+ inline bool operator()(Turn const& left, Turn const& right) const
+ {
+ segment_identifier const& sl = left.operations[0].seg_id;
+ segment_identifier const& sr = right.operations[0].seg_id;
+
+ return sl == sr
+ ? use_distance(left, right)
+ : sl < sr
+ ;
+
+ }
+ };
+
+
+
+public :
+
+ template <typename Point, typename Geometry>
+ static inline bool included(Point const& point, Geometry const& geometry)
+ {
+ return following::action_selector<OverlayType>::included(point, geometry);
+ }
+
+ template<typename Turns, typename OutputIterator>
+ static inline OutputIterator apply(LineString const& linestring, Polygon const& polygon,
+ detail::overlay::operation_type , // TODO: this parameter might be redundant
+ Turns& turns, OutputIterator out)
+ {
+ typedef typename boost::range_iterator<Turns>::type turn_iterator;
+ typedef typename boost::range_value<Turns>::type turn_type;
+ typedef typename boost::range_iterator
+ <
+ typename turn_type::container_type
+ >::type turn_operation_iterator_type;
+
+ typedef following::action_selector<OverlayType> action;
+
+ // Sort intersection points on segments-along-linestring, and distance
+ // (like in enrich is done for poly/poly)
+ std::sort(boost::begin(turns), boost::end(turns), sort_on_segment<turn_type>());
+
+ LineStringOut current_piece;
+ geometry::segment_identifier current_segment_id(0, -1, -1, -1);
+
+ // Iterate through all intersection points (they are ordered along the line)
+ bool entered = false;
+ bool first = true;
+ for (turn_iterator it = boost::begin(turns); it != boost::end(turns); ++it)
+ {
+ turn_operation_iterator_type iit = boost::begin(it->operations);
+
+ if (following::was_entered(*it, *iit, first, linestring, polygon))
+ {
+ debug_traverse(*it, *iit, "-> Was entered");
+ entered = true;
+ }
+
+ if (following::is_staying_inside(*it, *iit, entered, first, linestring, polygon))
+ {
+ debug_traverse(*it, *iit, "-> Staying inside");
+
+ entered = true;
+ }
+ else if (following::is_entering(*it, *iit))
+ {
+ debug_traverse(*it, *iit, "-> Entering");
+
+ entered = true;
+ action::enter(current_piece, linestring, current_segment_id, iit->seg_id.segment_index, it->point, *iit, out);
+ }
+ else if (following::is_leaving(*it, *iit, entered, first, linestring, polygon))
+ {
+ debug_traverse(*it, *iit, "-> Leaving");
+
+ entered = false;
+ action::leave(current_piece, linestring, current_segment_id, iit->seg_id.segment_index, it->point, *iit, out);
+ }
+ first = false;
+ }
+
+ if (action::is_entered(entered))
+ {
+ geometry::copy_segments<false>(linestring, current_segment_id,
+ boost::size(linestring) - 1,
+ current_piece);
+ }
+
+ // Output the last one, if applicable
+ if (current_piece.size() > 1)
+ {
+ *out++ = current_piece;
+ }
+ return out;
+ }
+
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_FOLLOW_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp b/src/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
new file mode 100644
index 0000000..019c3ba
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp
@@ -0,0 +1,146 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_INTERSECTION_POINTS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_INTERSECTION_POINTS_HPP
+
+
+#include <cstddef>
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+
+#include <boost/geometry/geometries/segment.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace get_intersection_points
+{
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename TurnInfo
+>
+struct get_turn_without_info
+{
+ typedef strategy_intersection
+ <
+ typename cs_tag<typename TurnInfo::point_type>::type,
+ Point1,
+ Point2,
+ typename TurnInfo::point_type
+ > si;
+
+ typedef typename si::segment_intersection_strategy_type strategy;
+
+
+
+ template <typename OutputIterator>
+ static inline OutputIterator apply(
+ Point1 const& pi, Point1 const& pj, Point1 const& pk,
+ Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ TurnInfo const& ,
+ OutputIterator out)
+ {
+ typedef model::referring_segment<Point1 const> segment_type1;
+ typedef model::referring_segment<Point1 const> segment_type2;
+ segment_type1 p1(pi, pj), p2(pj, pk);
+ segment_type2 q1(qi, qj), q2(qj, qk);
+
+ //
+ typename strategy::return_type result = strategy::apply(p1, q1);
+
+ for (std::size_t i = 0; i < result.template get<0>().count; i++)
+ {
+
+ TurnInfo tp;
+ geometry::convert(result.template get<0>().intersections[i], tp.point);
+ *out++ = tp;
+ }
+
+ return out;
+ }
+};
+
+}} // namespace detail::get_intersection_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Turns
+>
+inline void get_intersection_points(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Turns& turns)
+{
+ concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
+
+ typedef detail::get_intersection_points::get_turn_without_info
+ <
+ typename point_type<Geometry1>::type,
+ typename point_type<Geometry2>::type,
+ typename boost::range_value<Turns>::type
+ > TurnPolicy;
+
+ typedef typename strategy_intersection
+ <
+ typename cs_tag<Geometry1>::type,
+ Geometry1,
+ Geometry2,
+ typename boost::range_value<Turns>::type
+ >::segment_intersection_strategy_type segment_intersection_strategy_type;
+
+ detail::get_turns::no_interrupt_policy interrupt_policy;
+
+ boost::mpl::if_c
+ <
+ reverse_dispatch<Geometry1, Geometry2>::type::value,
+ dispatch::get_turns_reversed
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1, Geometry2,
+ false, false,
+ Turns, TurnPolicy,
+ //segment_intersection_strategy_type,
+ detail::get_turns::no_interrupt_policy
+ >,
+ dispatch::get_turns
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1, Geometry2,
+ false, false,
+ Turns, TurnPolicy,
+ //segment_intersection_strategy_type,
+ detail::get_turns::no_interrupt_policy
+ >
+ >::type::apply(
+ 0, geometry1,
+ 1, geometry2,
+ turns, interrupt_policy);
+}
+
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_INTERSECTION_POINTS_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/get_relative_order.hpp b/src/boost/geometry/algorithms/detail/overlay/get_relative_order.hpp
new file mode 100644
index 0000000..522ef68
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/get_relative_order.hpp
@@ -0,0 +1,108 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RELATIVE_ORDER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RELATIVE_ORDER_HPP
+
+
+#include <boost/geometry/algorithms/distance.hpp>
+
+#include <boost/geometry/strategies/intersection.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+/*!
+ \brief Get relative order
+ \details Can indicate which of two segments R and S,
+ both crossing a common segment P, comes first.
+ If the two segments cross P very close (e.g. in a spike),
+ the distance between the intersection points can be zero,
+ but we still need to know which comes first.
+ Therefore, it is useful that using sides we are able to discover this.
+ */
+template <typename Point1>
+struct get_relative_order
+{
+ typedef strategy_intersection
+ <
+ typename cs_tag<Point1>::type,
+ Point1,
+ Point1,
+ Point1
+ > si;
+
+ typedef typename si::side_strategy_type strategy;
+
+ template <typename Point>
+ static inline int value_via_product(Point const& ti, Point const& tj,
+ Point const& ui, Point const& uj, int factor)
+ {
+ int const side_ti_u = strategy::apply(ti, tj, ui);
+ int const side_tj_u = strategy::apply(ti, tj, uj);
+
+#ifdef BOOST_GEOMETRY_DEBUG_RELATIVE_ORDER
+ std::cout << (factor == 1 ? " r//s " : " s//r ")
+ << side_ti_u << " / " << side_tj_u;
+#endif
+
+ return side_ti_u * side_tj_u >= 0
+ ? factor * (side_ti_u != 0 ? side_ti_u : side_tj_u)
+ : 0;
+ }
+
+
+ static inline int apply(
+ Point1 const& pi, Point1 const& pj,
+ Point1 const& ri, Point1 const& rj,
+ Point1 const& si, Point1 const& sj)
+ {
+ int const side_ri_p = strategy::apply(pi, pj, ri);
+ int const side_si_p = strategy::apply(pi, pj, si);
+
+#ifdef BOOST_GEOMETRY_DEBUG_RELATIVE_ORDER
+ int const side_rj_p = strategy::apply(pi, pj, rj);
+ int const side_sj_p = strategy::apply(pi, pj, sj);
+ std::cout << "r//p: " << side_ri_p << " / " << side_rj_p;
+ std::cout << " s//p: " << side_si_p << " / " << side_sj_p;
+#endif
+
+ int value = value_via_product(si, sj, ri, rj, 1);
+ if (value == 0)
+ {
+ value = value_via_product(ri, rj, si, sj, -1);
+ }
+
+ int const order = side_ri_p * side_ri_p * side_si_p * value;
+
+#ifdef BOOST_GEOMETRY_DEBUG_RELATIVE_ORDER
+ std::cout
+ << " o: " << order
+ << std::endl << std::endl;
+#endif
+
+ return order;
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RELATIVE_ORDER_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/get_ring.hpp b/src/boost/geometry/algorithms/detail/overlay/get_ring.hpp
new file mode 100644
index 0000000..c2c6980
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/get_ring.hpp
@@ -0,0 +1,102 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
+
+
+#include <boost/assert.hpp>
+#include <boost/range.hpp>
+
+
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+template<typename Tag>
+struct get_ring
+{};
+
+// A container of rings (multi-ring but that does not exist)
+// gets the "void" tag and is dispatched here.
+template<>
+struct get_ring<void>
+{
+ template<typename Container>
+ static inline typename boost::range_value<Container>::type const&
+ apply(ring_identifier const& id, Container const& container)
+ {
+ return container[id.multi_index];
+ }
+};
+
+
+
+
+template<>
+struct get_ring<ring_tag>
+{
+ template<typename Ring>
+ static inline Ring const& apply(ring_identifier const& , Ring const& ring)
+ {
+ return ring;
+ }
+};
+
+
+template<>
+struct get_ring<box_tag>
+{
+ template<typename Box>
+ static inline Box const& apply(ring_identifier const& ,
+ Box const& box)
+ {
+ return box;
+ }
+};
+
+
+template<>
+struct get_ring<polygon_tag>
+{
+ template<typename Polygon>
+ static inline typename ring_return_type<Polygon const>::type const apply(
+ ring_identifier const& id,
+ Polygon const& polygon)
+ {
+ BOOST_ASSERT
+ (
+ id.ring_index >= -1
+ && id.ring_index < int(boost::size(interior_rings(polygon)))
+ );
+ return id.ring_index < 0
+ ? exterior_ring(polygon)
+ : interior_rings(polygon)[id.ring_index];
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/src/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
new file mode 100644
index 0000000..b8320d9
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp
@@ -0,0 +1,1094 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
+
+
+#include <boost/assert.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+
+#include <boost/geometry/geometries/segment.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
+class turn_info_exception : public geometry::exception
+{
+ std::string message;
+public:
+
+ // NOTE: "char" will be replaced by enum in future version
+ inline turn_info_exception(char const method)
+ {
+ message = "Boost.Geometry Turn exception: ";
+ message += method;
+ }
+
+ virtual ~turn_info_exception() throw()
+ {}
+
+ virtual char const* what() const throw()
+ {
+ return message.c_str();
+ }
+};
+#endif
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+struct base_turn_handler
+{
+ // Returns true if both sides are opposite
+ static inline bool opposite(int side1, int side2)
+ {
+ // We cannot state side1 == -side2, because 0 == -0
+ // So either side1*side2==-1 or side1==-side2 && side1 != 0
+ return side1 * side2 == -1;
+ }
+
+ // Same side of a segment (not being 0)
+ static inline bool same(int side1, int side2)
+ {
+ return side1 * side2 == 1;
+ }
+
+ // Both continue
+ template <typename TurnInfo>
+ static inline void both(TurnInfo& ti, operation_type const op)
+ {
+ ti.operations[0].operation = op;
+ ti.operations[1].operation = op;
+ }
+
+ // If condition, first union/second intersection, else vice versa
+ template <typename TurnInfo>
+ static inline void ui_else_iu(bool condition, TurnInfo& ti)
+ {
+ ti.operations[0].operation = condition
+ ? operation_union : operation_intersection;
+ ti.operations[1].operation = condition
+ ? operation_intersection : operation_union;
+ }
+
+ // If condition, both union, else both intersection
+ template <typename TurnInfo>
+ static inline void uu_else_ii(bool condition, TurnInfo& ti)
+ {
+ both(ti, condition ? operation_union : operation_intersection);
+ }
+};
+
+
+template
+<
+ typename TurnInfo,
+ typename SideStrategy
+>
+struct touch_interior : public base_turn_handler
+{
+ // Index: 0, P is the interior, Q is touching and vice versa
+ template
+ <
+ int Index,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(
+ Point1 const& pi, Point1 const& pj, Point1 const& ,
+ Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ TurnInfo& ti,
+ IntersectionInfo const& intersection_info,
+ DirInfo const& dir_info)
+ {
+ ti.method = method_touch_interior;
+ geometry::convert(intersection_info.intersections[0], ti.point);
+
+ // Both segments of q touch segment p somewhere in its interior
+ // 1) We know: if q comes from LEFT or RIGHT
+ // (i.e. dir_info.sides.get<Index,0>() == 1 or -1)
+ // 2) Important is: if q_k goes to LEFT, RIGHT, COLLINEAR
+ // and, if LEFT/COLL, if it is lying LEFT or RIGHT w.r.t. q_i
+
+ static int const index_p = Index;
+ static int const index_q = 1 - Index;
+
+ int const side_qi_p = dir_info.sides.template get<index_q, 0>();
+ int const side_qk_p = SideStrategy::apply(pi, pj, qk);
+
+ if (side_qi_p == -side_qk_p)
+ {
+ // Q crosses P from left->right or from right->left (test "ML1")
+ // Union: folow P (left->right) or Q (right->left)
+ // Intersection: other turn
+ int index = side_qk_p == -1 ? index_p : index_q;
+ ti.operations[index].operation = operation_union;
+ ti.operations[1 - index].operation = operation_intersection;
+ return;
+ }
+
+ int const side_qk_q = SideStrategy::apply(qi, qj, qk);
+
+ if (side_qi_p == -1 && side_qk_p == -1 && side_qk_q == 1)
+ {
+ // Q turns left on the right side of P (test "MR3")
+ // Both directions for "intersection"
+ both(ti, operation_intersection);
+ }
+ else if (side_qi_p == 1 && side_qk_p == 1 && side_qk_q == -1)
+ {
+ // Q turns right on the left side of P (test "ML3")
+ // Union: take both operation
+ // Intersection: skip
+ both(ti, operation_union);
+ }
+ else if (side_qi_p == side_qk_p && side_qi_p == side_qk_q)
+ {
+ // Q turns left on the left side of P (test "ML2")
+ // or Q turns right on the right side of P (test "MR2")
+ // Union: take left turn (Q if Q turns left, P if Q turns right)
+ // Intersection: other turn
+ int index = side_qk_q == 1 ? index_q : index_p;
+ ti.operations[index].operation = operation_union;
+ ti.operations[1 - index].operation = operation_intersection;
+ }
+ else if (side_qk_p == 0)
+ {
+ // Q intersects on interior of P and continues collinearly
+ if (side_qk_q == side_qi_p)
+ {
+ // Collinearly in the same direction
+ // (Q comes from left of P and turns left,
+ // OR Q comes from right of P and turns right)
+ // Omit intersection point.
+ // Union: just continue
+ // Intersection: just continue
+ both(ti, operation_continue);
+ }
+ else
+ {
+ // Opposite direction, which is never travelled.
+ // If Q turns left, P continues for intersection
+ // If Q turns right, P continues for union
+ ti.operations[Index].operation = side_qk_q == 1
+ ? operation_intersection
+ : operation_union;
+ ti.operations[1 - Index].operation = operation_blocked;
+ }
+ }
+ else
+ {
+ // Should not occur!
+ ti.method = method_error;
+ }
+ }
+};
+
+
+template
+<
+ typename TurnInfo,
+ typename SideStrategy
+>
+struct touch : public base_turn_handler
+{
+ static inline bool between(int side1, int side2, int turn)
+ {
+ return side1 == side2 && ! opposite(side1, turn);
+ }
+
+ /*static inline void block_second(bool block, TurnInfo& ti)
+ {
+ if (block)
+ {
+ ti.operations[1].operation = operation_blocked;
+ }
+ }*/
+
+
+ template
+ <
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(
+ Point1 const& pi, Point1 const& pj, Point1 const& pk,
+ Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ TurnInfo& ti,
+ IntersectionInfo const& intersection_info,
+ DirInfo const& dir_info)
+ {
+ ti.method = method_touch;
+ geometry::convert(intersection_info.intersections[0], ti.point);
+
+ int const side_qi_p1 = dir_info.sides.template get<1, 0>();
+ int const side_qk_p1 = SideStrategy::apply(pi, pj, qk);
+
+
+ // If Qi and Qk are both at same side of Pi-Pj,
+ // or collinear (so: not opposite sides)
+ if (! opposite(side_qi_p1, side_qk_p1))
+ {
+ int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
+ int const side_pk_p = SideStrategy::apply(pi, pj, pk);
+ int const side_qk_q = SideStrategy::apply(qi, qj, qk);
+
+ bool const both_continue = side_pk_p == 0 && side_qk_q == 0;
+ bool const robustness_issue_in_continue = both_continue && side_pk_q2 != 0;
+
+ bool const q_turns_left = side_qk_q == 1;
+ bool const block_q = side_qk_p1 == 0
+ && ! same(side_qi_p1, side_qk_q)
+ && ! robustness_issue_in_continue
+ ;
+
+ // If Pk at same side as Qi/Qk
+ // (the "or" is for collinear case)
+ // or Q is fully collinear && P turns not to left
+ if (side_pk_p == side_qi_p1
+ || side_pk_p == side_qk_p1
+ || (side_qi_p1 == 0 && side_qk_p1 == 0 && side_pk_p != -1)
+ )
+ {
+ // Collinear -> lines join, continue
+ // (#BRL2)
+ if (side_pk_q2 == 0 && ! block_q)
+ {
+ both(ti, operation_continue);
+ return;
+ }
+
+ int const side_pk_q1 = SideStrategy::apply(qi, qj, pk);
+
+
+ // Collinear opposite case -> block P
+ // (#BRL4, #BLR8)
+ if (side_pk_q1 == 0)
+ {
+ ti.operations[0].operation = operation_blocked;
+ // Q turns right -> union (both independent),
+ // Q turns left -> intersection
+ ti.operations[1].operation = block_q ? operation_blocked
+ : q_turns_left ? operation_intersection
+ : operation_union;
+ return;
+ }
+
+ // Pk between Qi and Qk
+ // (#BRL3, #BRL7)
+ if (between(side_pk_q1, side_pk_q2, side_qk_q))
+ {
+ ui_else_iu(q_turns_left, ti);
+ if (block_q)
+ {
+ ti.operations[1].operation = operation_blocked;
+ }
+ //block_second(block_q, ti);
+ return;
+ }
+
+ // Pk between Qk and P, so left of Qk (if Q turns right) and vv
+ // (#BRL1)
+ if (side_pk_q2 == -side_qk_q)
+ {
+ ui_else_iu(! q_turns_left, ti);
+ return;
+ }
+
+ //
+ // (#BRL5, #BRL9)
+ if (side_pk_q1 == -side_qk_q)
+ {
+ uu_else_ii(! q_turns_left, ti);
+ if (block_q)
+ {
+ ti.operations[1].operation = operation_blocked;
+ }
+ //block_second(block_q, ti);
+ return;
+ }
+ }
+ else
+ {
+ // Pk at other side than Qi/Pk
+ int const side_qk_q = SideStrategy::apply(qi, qj, qk);
+ bool const q_turns_left = side_qk_q == 1;
+
+ ti.operations[0].operation = q_turns_left
+ ? operation_intersection
+ : operation_union;
+ ti.operations[1].operation = block_q
+ ? operation_blocked
+ : side_qi_p1 == 1 || side_qk_p1 == 1
+ ? operation_union
+ : operation_intersection;
+
+ return;
+ }
+ }
+ else
+ {
+ // From left to right or from right to left
+ int const side_pk_p = SideStrategy::apply(pi, pj, pk);
+ bool const right_to_left = side_qk_p1 == 1;
+
+ // If p turns into direction of qi (1,2)
+ if (side_pk_p == side_qi_p1)
+ {
+ int const side_pk_q1 = SideStrategy::apply(qi, qj, pk);
+
+ // Collinear opposite case -> block P
+ if (side_pk_q1 == 0)
+ {
+ ti.operations[0].operation = operation_blocked;
+ ti.operations[1].operation = right_to_left
+ ? operation_union : operation_intersection;
+ return;
+ }
+
+ if (side_pk_q1 == side_qk_p1)
+ {
+ uu_else_ii(right_to_left, ti);
+ return;
+ }
+ }
+
+ // If p turns into direction of qk (4,5)
+ if (side_pk_p == side_qk_p1)
+ {
+ int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
+
+ // Collinear case -> lines join, continue
+ if (side_pk_q2 == 0)
+ {
+ both(ti, operation_continue);
+ return;
+ }
+ if (side_pk_q2 == side_qk_p1)
+ {
+ ui_else_iu(right_to_left, ti);
+ return;
+ }
+ }
+ // otherwise (3)
+ ui_else_iu(! right_to_left, ti);
+ return;
+ }
+
+#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS
+ // Normally a robustness issue.
+ // TODO: more research if still occuring
+ std::cout << "Not yet handled" << std::endl
+ << "pi " << get<0>(pi) << " , " << get<1>(pi)
+ << " pj " << get<0>(pj) << " , " << get<1>(pj)
+ << " pk " << get<0>(pk) << " , " << get<1>(pk)
+ << std::endl
+ << "qi " << get<0>(qi) << " , " << get<1>(qi)
+ << " qj " << get<0>(qj) << " , " << get<1>(qj)
+ << " qk " << get<0>(qk) << " , " << get<1>(qk)
+ << std::endl;
+#endif
+
+ }
+};
+
+
+template
+<
+ typename TurnInfo,
+ typename SideStrategy
+>
+struct equal : public base_turn_handler
+{
+ template
+ <
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(
+ Point1 const& pi, Point1 const& pj, Point1 const& pk,
+ Point2 const& , Point2 const& qj, Point2 const& qk,
+ TurnInfo& ti,
+ IntersectionInfo const& intersection_info,
+ DirInfo const& )
+ {
+ ti.method = method_equal;
+ // Copy the SECOND intersection point
+ geometry::convert(intersection_info.intersections[1], ti.point);
+
+ int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
+ int const side_pk_p = SideStrategy::apply(pi, pj, pk);
+ int const side_qk_p = SideStrategy::apply(pi, pj, qk);
+
+ // If pk is collinear with qj-qk, they continue collinearly.
+ // This can be on either side of p1 (== q1), or collinear
+ // The second condition checks if they do not continue
+ // oppositely
+ if (side_pk_q2 == 0 && side_pk_p == side_qk_p)
+ {
+ both(ti, operation_continue);
+ return;
+ }
+
+
+ // If they turn to same side (not opposite sides)
+ if (! opposite(side_pk_p, side_qk_p))
+ {
+ int const side_pk_q2 = SideStrategy::apply(qj, qk, pk);
+
+ // If pk is left of q2 or collinear: p: union, q: intersection
+ ui_else_iu(side_pk_q2 != -1, ti);
+ }
+ else
+ {
+ // They turn opposite sides. If p turns left (or collinear),
+ // p: union, q: intersection
+ ui_else_iu(side_pk_p != -1, ti);
+ }
+ }
+};
+
+
+template
+<
+ typename TurnInfo,
+ typename AssignPolicy
+>
+struct equal_opposite : public base_turn_handler
+{
+ template
+ <
+ typename Point1,
+ typename Point2,
+ typename OutputIterator,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(Point1 const& pi, Point2 const& qi,
+ /* by value: */ TurnInfo tp,
+ OutputIterator& out,
+ IntersectionInfo const& intersection_info,
+ DirInfo const& dir_info)
+ {
+ // For equal-opposite segments, normally don't do anything.
+ if (AssignPolicy::include_opposite)
+ {
+ tp.method = method_equal;
+ for (int i = 0; i < 2; i++)
+ {
+ tp.operations[i].operation = operation_opposite;
+ }
+ for (unsigned int i = 0; i < intersection_info.count; i++)
+ {
+ geometry::convert(intersection_info.intersections[i], tp.point);
+ AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ *out++ = tp;
+ }
+ }
+ }
+};
+
+template
+<
+ typename TurnInfo,
+ typename SideStrategy
+>
+struct collinear : public base_turn_handler
+{
+ /*
+ arrival P pk//p1 qk//q1 product* case result
+ 1 1 1 CLL1 ui
+ -1 1 -1 CLL2 iu
+ 1 1 1 CLR1 ui
+ -1 -1 1 CLR2 ui
+
+ 1 -1 -1 CRL1 iu
+ -1 1 -1 CRL2 iu
+ 1 -1 -1 CRR1 iu
+ -1 -1 1 CRR2 ui
+
+ 1 0 0 CC1 cc
+ -1 0 0 CC2 cc
+
+ *product = arrival * (pk//p1 or qk//q1)
+
+ Stated otherwise:
+ - if P arrives: look at turn P
+ - if Q arrives: look at turn Q
+ - if P arrives and P turns left: union for P
+ - if P arrives and P turns right: intersection for P
+ - if Q arrives and Q turns left: union for Q (=intersection for P)
+ - if Q arrives and Q turns right: intersection for Q (=union for P)
+
+ ROBUSTNESS: p and q are collinear, so you would expect
+ that side qk//p1 == pk//q1. But that is not always the case
+ in near-epsilon ranges. Then decision logic is different.
+ If p arrives, q is further, so the angle qk//p1 is (normally)
+ more precise than pk//p1
+
+ */
+ template
+ <
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(
+ Point1 const& pi, Point1 const& pj, Point1 const& pk,
+ Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ TurnInfo& ti,
+ IntersectionInfo const& intersection_info,
+ DirInfo const& dir_info)
+ {
+ ti.method = method_collinear;
+ geometry::convert(intersection_info.intersections[1], ti.point);
+
+ int const arrival = dir_info.arrival[0];
+ // Should not be 0, this is checked before
+ BOOST_ASSERT(arrival != 0);
+
+ int const side_p = SideStrategy::apply(pi, pj, pk);
+ int const side_q = SideStrategy::apply(qi, qj, qk);
+
+ // If p arrives, use p, else use q
+ int const side_p_or_q = arrival == 1
+ ? side_p
+ : side_q
+ ;
+
+ int const side_pk = SideStrategy::apply(qi, qj, pk);
+ int const side_qk = SideStrategy::apply(pi, pj, qk);
+
+ // See comments above,
+ // resulting in a strange sort of mathematic rule here:
+ // The arrival-info multiplied by the relevant side
+ // delivers a consistent result.
+
+ int const product = arrival * side_p_or_q;
+
+ // Robustness: side_p is supposed to be equal to side_pk (because p/q are collinear)
+ // and side_q to side_qk
+ bool const robustness_issue = side_pk != side_p || side_qk != side_q;
+
+ if (robustness_issue)
+ {
+ handle_robustness(ti, arrival, side_p, side_q, side_pk, side_qk);
+ }
+ else if(product == 0)
+ {
+ both(ti, operation_continue);
+ }
+ else
+ {
+ ui_else_iu(product == 1, ti);
+ }
+ }
+
+ static inline void handle_robustness(TurnInfo& ti, int arrival,
+ int side_p, int side_q, int side_pk, int side_qk)
+ {
+ // We take the longer one, i.e. if q arrives in p (arrival == -1),
+ // then p exceeds q and we should take p for a union...
+
+ bool use_p_for_union = arrival == -1;
+
+ // ... unless one of the sides consistently directs to the other side
+ int const consistent_side_p = side_p == side_pk ? side_p : 0;
+ int const consistent_side_q = side_q == side_qk ? side_q : 0;
+ if (arrival == -1 && (consistent_side_p == -1 || consistent_side_q == 1))
+ {
+ use_p_for_union = false;
+ }
+ if (arrival == 1 && (consistent_side_p == 1 || consistent_side_q == -1))
+ {
+ use_p_for_union = true;
+ }
+
+ //std::cout << "ROBUSTNESS -> Collinear "
+ // << " arr: " << arrival
+ // << " dir: " << side_p << " " << side_q
+ // << " rev: " << side_pk << " " << side_qk
+ // << " cst: " << cside_p << " " << cside_q
+ // << std::boolalpha << " " << use_p_for_union
+ // << std::endl;
+
+ ui_else_iu(use_p_for_union, ti);
+ }
+
+};
+
+template
+<
+ typename TurnInfo,
+ typename SideStrategy,
+ typename AssignPolicy
+>
+struct collinear_opposite : public base_turn_handler
+{
+private :
+ /*
+ arrival P arrival Q pk//p1 qk//q1 case result2 result
+ --------------------------------------------------------------
+ 1 1 1 -1 CLO1 ix xu
+ 1 1 1 0 CLO2 ix (xx)
+ 1 1 1 1 CLO3 ix xi
+
+ 1 1 0 -1 CCO1 (xx) xu
+ 1 1 0 0 CCO2 (xx) (xx)
+ 1 1 0 1 CCO3 (xx) xi
+
+ 1 1 -1 -1 CRO1 ux xu
+ 1 1 -1 0 CRO2 ux (xx)
+ 1 1 -1 1 CRO3 ux xi
+
+ -1 1 -1 CXO1 xu
+ -1 1 0 CXO2 (xx)
+ -1 1 1 CXO3 xi
+
+ 1 -1 1 CXO1 ix
+ 1 -1 0 CXO2 (xx)
+ 1 -1 -1 CXO3 ux
+ */
+
+ template
+ <
+ int Index,
+ typename Point,
+ typename IntersectionInfo
+ >
+ static inline bool set_tp(Point const& ri, Point const& rj, Point const& rk,
+ TurnInfo& tp, IntersectionInfo const& intersection_info)
+ {
+ int const side_rk_r = SideStrategy::apply(ri, rj, rk);
+ operation_type blocked = operation_blocked;
+ switch(side_rk_r)
+ {
+
+ case 1 :
+ // Turning left on opposite collinear: intersection
+ tp.operations[Index].operation = operation_intersection;
+ break;
+ case -1 :
+ // Turning right on opposite collinear: union
+ tp.operations[Index].operation = operation_union;
+ break;
+ case 0 :
+ // No turn on opposite collinear: block, do not traverse
+ // But this "xx" is usually ignored, it is useless to include
+ // two operations blocked, so the whole point does not need
+ // to be generated.
+ // So return false to indicate nothing is to be done.
+ if (AssignPolicy::include_opposite)
+ {
+ tp.operations[Index].operation = operation_opposite;
+ blocked = operation_opposite;
+ }
+ else
+ {
+ return false;
+ }
+ break;
+ }
+
+ // The other direction is always blocked when collinear opposite
+ tp.operations[1 - Index].operation = blocked;
+
+ // If P arrives within Q, set info on P (which is done above, index=0),
+ // this turn-info belongs to the second intersection point, index=1
+ // (see e.g. figure CLO1)
+ geometry::convert(intersection_info.intersections[1 - Index], tp.point);
+ return true;
+ }
+
+public:
+ template
+ <
+ typename Point1,
+ typename Point2,
+ typename OutputIterator,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(
+ Point1 const& pi, Point1 const& pj, Point1 const& pk,
+ Point2 const& qi, Point2 const& qj, Point2 const& qk,
+
+ // Opposite collinear can deliver 2 intersection points,
+ TurnInfo const& tp_model,
+ OutputIterator& out,
+
+ IntersectionInfo const& intersection_info,
+ DirInfo const& dir_info)
+ {
+ TurnInfo tp = tp_model;
+
+ tp.method = method_collinear;
+
+ // If P arrives within Q, there is a turn dependent on P
+ if (dir_info.arrival[0] == 1
+ && set_tp<0>(pi, pj, pk, tp, intersection_info))
+ {
+ AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ *out++ = tp;
+ }
+
+ // If Q arrives within P, there is a turn dependent on Q
+ if (dir_info.arrival[1] == 1
+ && set_tp<1>(qi, qj, qk, tp, intersection_info))
+ {
+ AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ *out++ = tp;
+ }
+
+ if (AssignPolicy::include_opposite)
+ {
+ // Handle cases not yet handled above
+ if ((dir_info.arrival[1] == -1 && dir_info.arrival[0] == 0)
+ || (dir_info.arrival[0] == -1 && dir_info.arrival[1] == 0))
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ tp.operations[i].operation = operation_opposite;
+ }
+ for (unsigned int i = 0; i < intersection_info.count; i++)
+ {
+ geometry::convert(intersection_info.intersections[i], tp.point);
+ AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info);
+ *out++ = tp;
+ }
+ }
+ }
+
+ }
+};
+
+
+template
+<
+ typename TurnInfo,
+ typename SideStrategy
+>
+struct crosses : public base_turn_handler
+{
+ template
+ <
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(
+ Point1 const& , Point1 const& , Point1 const& ,
+ Point2 const& , Point2 const& , Point2 const& ,
+ TurnInfo& ti,
+ IntersectionInfo const& intersection_info,
+ DirInfo const& dir_info)
+ {
+ ti.method = method_crosses;
+ geometry::convert(intersection_info.intersections[0], ti.point);
+
+ // In all casees:
+ // If Q crosses P from left to right
+ // Union: take P
+ // Intersection: take Q
+ // Otherwise: vice versa
+ int const side_qi_p1 = dir_info.sides.template get<1, 0>();
+ int const index = side_qi_p1 == 1 ? 0 : 1;
+ ti.operations[index].operation = operation_union;
+ ti.operations[1 - index].operation = operation_intersection;
+ }
+};
+
+template<typename TurnInfo>
+struct only_convert
+{
+ template<typename IntersectionInfo>
+ static inline void apply(TurnInfo& ti, IntersectionInfo const& intersection_info)
+ {
+ ti.method = method_collinear;
+ geometry::convert(intersection_info.intersections[0], ti.point);
+ ti.operations[0].operation = operation_continue;
+ ti.operations[1].operation = operation_continue;
+ }
+};
+
+/*!
+\brief Policy doing nothing
+\details get_turn_info can have an optional policy to get/assign some
+ extra information. By default it does not, and this class
+ is that default.
+ */
+struct assign_null_policy
+{
+ static bool const include_no_turn = false;
+ static bool const include_degenerate = false;
+ static bool const include_opposite = false;
+
+ template
+ <
+ typename Info,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(Info& , Point1 const& , Point2 const&, IntersectionInfo const&, DirInfo const&)
+ {}
+
+};
+
+
+/*!
+ \brief Turn information: intersection point, method, and turn information
+ \details Information necessary for traversal phase (a phase
+ of the overlay process). The information is gathered during the
+ get_turns (segment intersection) phase.
+ \tparam Point1 point type of first segment
+ \tparam Point2 point type of second segment
+ \tparam TurnInfo type of class getting intersection and turn info
+ \tparam AssignPolicy policy to assign extra info,
+ e.g. to calculate distance from segment's first points
+ to intersection points.
+ It also defines if a certain class of points
+ (degenerate, non-turns) should be included.
+ */
+template
+<
+ typename Point1,
+ typename Point2,
+ typename TurnInfo,
+ typename AssignPolicy
+>
+struct get_turn_info
+{
+ typedef strategy_intersection
+ <
+ typename cs_tag<typename TurnInfo::point_type>::type,
+ Point1,
+ Point2,
+ typename TurnInfo::point_type
+ > si;
+
+ typedef typename si::segment_intersection_strategy_type strategy;
+
+ // Intersect pi-pj with qi-qj
+ // The points pk and qk are only used do determine more information
+ // about the turn.
+ template <typename OutputIterator>
+ static inline OutputIterator apply(
+ Point1 const& pi, Point1 const& pj, Point1 const& pk,
+ Point2 const& qi, Point2 const& qj, Point2 const& qk,
+ TurnInfo const& tp_model,
+ OutputIterator out)
+ {
+ typedef model::referring_segment<Point1 const> segment_type1;
+ typedef model::referring_segment<Point1 const> segment_type2;
+ segment_type1 p1(pi, pj), p2(pj, pk);
+ segment_type2 q1(qi, qj), q2(qj, qk);
+
+ typename strategy::return_type result = strategy::apply(p1, q1);
+
+ char const method = result.template get<1>().how;
+
+ // Copy, to copy possibly extended fields
+ TurnInfo tp = tp_model;
+
+
+ // Select method and apply
+ switch(method)
+ {
+ case 'a' : // collinear, "at"
+ case 'f' : // collinear, "from"
+ case 's' : // starts from the middle
+ if (AssignPolicy::include_no_turn
+ && result.template get<0>().count > 0)
+ {
+ only_convert<TurnInfo>::apply(tp,
+ result.template get<0>());
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
+ *out++ = tp;
+ }
+ break;
+
+ case 'd' : // disjoint: never do anything
+ break;
+
+ case 'm' :
+ {
+ typedef touch_interior
+ <
+ TurnInfo,
+ typename si::side_strategy_type
+ > policy;
+
+ // If Q (1) arrives (1)
+ if (result.template get<1>().arrival[1] == 1)
+ {
+ policy::template apply<0>(pi, pj, pk, qi, qj, qk,
+ tp, result.template get<0>(), result.template get<1>());
+ }
+ else
+ {
+ // Swap p/q
+ policy::template apply<1>(qi, qj, qk, pi, pj, pk,
+ tp, result.template get<0>(), result.template get<1>());
+ }
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
+ *out++ = tp;
+ }
+ break;
+ case 'i' :
+ {
+ typedef crosses
+ <
+ TurnInfo,
+ typename si::side_strategy_type
+ > policy;
+
+ policy::apply(pi, pj, pk, qi, qj, qk,
+ tp, result.template get<0>(), result.template get<1>());
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
+ *out++ = tp;
+ }
+ break;
+ case 't' :
+ {
+ // Both touch (both arrive there)
+ typedef touch
+ <
+ TurnInfo,
+ typename si::side_strategy_type
+ > policy;
+
+ policy::apply(pi, pj, pk, qi, qj, qk,
+ tp, result.template get<0>(), result.template get<1>());
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
+ *out++ = tp;
+ }
+ break;
+ case 'e':
+ {
+ if (! result.template get<1>().opposite)
+ {
+ // Both equal
+ // or collinear-and-ending at intersection point
+ typedef equal
+ <
+ TurnInfo,
+ typename si::side_strategy_type
+ > policy;
+
+ policy::apply(pi, pj, pk, qi, qj, qk,
+ tp, result.template get<0>(), result.template get<1>());
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
+ *out++ = tp;
+ }
+ else
+ {
+ equal_opposite
+ <
+ TurnInfo,
+ AssignPolicy
+ >::apply(pi, qi,
+ tp, out, result.template get<0>(), result.template get<1>());
+ }
+ }
+ break;
+ case 'c' :
+ {
+ // Collinear
+ if (! result.template get<1>().opposite)
+ {
+
+ if (result.template get<1>().arrival[0] == 0)
+ {
+ // Collinear, but similar thus handled as equal
+ equal
+ <
+ TurnInfo,
+ typename si::side_strategy_type
+ >::apply(pi, pj, pk, qi, qj, qk,
+ tp, result.template get<0>(), result.template get<1>());
+
+ // override assigned method
+ tp.method = method_collinear;
+ }
+ else
+ {
+ collinear
+ <
+ TurnInfo,
+ typename si::side_strategy_type
+ >::apply(pi, pj, pk, qi, qj, qk,
+ tp, result.template get<0>(), result.template get<1>());
+ }
+
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
+ *out++ = tp;
+ }
+ else
+ {
+ collinear_opposite
+ <
+ TurnInfo,
+ typename si::side_strategy_type,
+ AssignPolicy
+ >::apply(pi, pj, pk, qi, qj, qk,
+ tp, out, result.template get<0>(), result.template get<1>());
+ }
+ }
+ break;
+ case '0' :
+ {
+ // degenerate points
+ if (AssignPolicy::include_degenerate)
+ {
+ only_convert<TurnInfo>::apply(tp, result.template get<0>());
+ AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
+ *out++ = tp;
+ }
+ }
+ break;
+ default :
+ {
+#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
+ throw turn_info_exception(method);
+#endif
+ }
+ break;
+ }
+
+ return out;
+ }
+};
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/src/boost/geometry/algorithms/detail/overlay/get_turns.hpp
new file mode 100644
index 0000000..2662904
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/get_turns.hpp
@@ -0,0 +1,873 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
+
+
+#include <cstddef>
+#include <map>
+
+#include <boost/array.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/tuple/tuple.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/reverse_dispatch.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+#include <boost/geometry/views/detail/range_type.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+#include <boost/geometry/iterators/ever_circling_iterator.hpp>
+
+#include <boost/geometry/strategies/cartesian/cart_intersect.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
+#include <boost/geometry/strategies/intersection_result.hpp>
+
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
+
+
+#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
+
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
+
+#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
+# include <sstream>
+# include <boost/geometry/io/dsv/write.hpp>
+#endif
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace get_turns
+{
+
+
+struct no_interrupt_policy
+{
+ static bool const enabled = false;
+
+ template <typename Range>
+ static inline bool apply(Range const&)
+ {
+ return false;
+ }
+};
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2,
+ typename Section1, typename Section2,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+class get_turns_in_sections
+{
+ typedef typename closeable_view
+ <
+ typename range_type<Geometry1>::type const,
+ closure<Geometry1>::value
+ >::type cview_type1;
+ typedef typename closeable_view
+ <
+ typename range_type<Geometry2>::type const,
+ closure<Geometry2>::value
+ >::type cview_type2;
+
+ typedef typename reversible_view
+ <
+ cview_type1 const,
+ Reverse1 ? iterate_reverse : iterate_forward
+ >::type view_type1;
+ typedef typename reversible_view
+ <
+ cview_type2 const,
+ Reverse2 ? iterate_reverse : iterate_forward
+ >::type view_type2;
+
+ typedef typename boost::range_iterator
+ <
+ view_type1 const
+ >::type range1_iterator;
+
+ typedef typename boost::range_iterator
+ <
+ view_type2 const
+ >::type range2_iterator;
+
+
+ template <typename Geometry, typename Section>
+ static inline bool neighbouring(Section const& section,
+ int index1, int index2)
+ {
+ // About n-2:
+ // (square: range_count=5, indices 0,1,2,3
+ // -> 0-3 are adjacent, don't check on intersections)
+ // Also tested for open polygons, and/or duplicates
+ // About first condition: will be optimized by compiler (static)
+ // It checks if it is areal (box,ring,(multi)polygon
+ int const n = int(section.range_count);
+ return boost::is_same
+ <
+ typename tag_cast
+ <
+ typename geometry::point_type<Geometry1>::type,
+ areal_tag
+ >::type,
+ areal_tag
+ >::value
+ && index1 == 0
+ && index2 >= n - 2
+ ;
+ }
+
+
+public :
+ // Returns true if terminated, false if interrupted
+ static inline bool apply(
+ int source_id1, Geometry1 const& geometry1, Section1 const& sec1,
+ int source_id2, Geometry2 const& geometry2, Section2 const& sec2,
+ bool skip_larger,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
+ {
+ cview_type1 cview1(range_by_section(geometry1, sec1));
+ cview_type2 cview2(range_by_section(geometry2, sec2));
+ view_type1 view1(cview1);
+ view_type2 view2(cview2);
+
+ range1_iterator begin_range_1 = boost::begin(view1);
+ range1_iterator end_range_1 = boost::end(view1);
+
+ range2_iterator begin_range_2 = boost::begin(view2);
+ range2_iterator end_range_2 = boost::end(view2);
+
+ int const dir1 = sec1.directions[0];
+ int const dir2 = sec2.directions[0];
+ int index1 = sec1.begin_index;
+ int ndi1 = sec1.non_duplicate_index;
+
+ bool const same_source =
+ source_id1 == source_id2
+ && sec1.ring_id.multi_index == sec2.ring_id.multi_index
+ && sec1.ring_id.ring_index == sec2.ring_id.ring_index;
+
+ range1_iterator prev1, it1, end1;
+
+ get_start_point_iterator(sec1, view1, prev1, it1, end1,
+ index1, ndi1, dir1, sec2.bounding_box);
+
+ // We need a circular iterator because it might run through the closing point.
+ // One circle is actually enough but this one is just convenient.
+ ever_circling_iterator<range1_iterator> next1(begin_range_1, end_range_1, it1, true);
+ next1++;
+
+ // Walk through section and stop if we exceed the other box
+ // section 2: [--------------]
+ // section 1: |----|---|---|---|---|
+ for (prev1 = it1++, next1++;
+ it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box);
+ ++prev1, ++it1, ++index1, ++next1, ++ndi1)
+ {
+ ever_circling_iterator<range1_iterator> nd_next1(
+ begin_range_1, end_range_1, next1, true);
+ advance_to_non_duplicate_next(nd_next1, it1, sec1);
+
+ int index2 = sec2.begin_index;
+ int ndi2 = sec2.non_duplicate_index;
+
+ range2_iterator prev2, it2, end2;
+
+ get_start_point_iterator(sec2, view2, prev2, it2, end2,
+ index2, ndi2, dir2, sec1.bounding_box);
+ ever_circling_iterator<range2_iterator> next2(begin_range_2, end_range_2, it2, true);
+ next2++;
+
+ for (prev2 = it2++, next2++;
+ it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box);
+ ++prev2, ++it2, ++index2, ++next2, ++ndi2)
+ {
+ bool skip = same_source;
+ if (skip)
+ {
+ // If sources are the same (possibly self-intersecting):
+ // skip if it is a neighbouring segment.
+ // (including first-last segment
+ // and two segments with one or more degenerate/duplicate
+ // (zero-length) segments in between)
+
+ // Also skip if index1 < index2 to avoid getting all
+ // intersections twice (only do this on same source!)
+
+ skip = (skip_larger && index1 >= index2)
+ || ndi2 == ndi1 + 1
+ || neighbouring<Geometry1>(sec1, index1, index2)
+ ;
+ }
+
+ if (! skip)
+ {
+ // Move to the "non duplicate next"
+ ever_circling_iterator<range2_iterator> nd_next2(
+ begin_range_2, end_range_2, next2, true);
+ advance_to_non_duplicate_next(nd_next2, it2, sec2);
+
+ typedef typename boost::range_value<Turns>::type turn_info;
+ typedef typename turn_info::point_type ip;
+
+ turn_info ti;
+ ti.operations[0].seg_id = segment_identifier(source_id1,
+ sec1.ring_id.multi_index, sec1.ring_id.ring_index, index1),
+ ti.operations[1].seg_id = segment_identifier(source_id2,
+ sec2.ring_id.multi_index, sec2.ring_id.ring_index, index2),
+
+ ti.operations[0].other_id = ti.operations[1].seg_id;
+ ti.operations[1].other_id = ti.operations[0].seg_id;
+
+ std::size_t const size_before = boost::size(turns);
+
+ TurnPolicy::apply(*prev1, *it1, *nd_next1, *prev2, *it2, *nd_next2,
+ ti, std::back_inserter(turns));
+
+ if (InterruptPolicy::enabled)
+ {
+ if (interrupt_policy.apply(
+ std::make_pair(boost::begin(turns) + size_before,
+ boost::end(turns))))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+
+private :
+ typedef typename geometry::point_type<Geometry1>::type point1_type;
+ typedef typename geometry::point_type<Geometry2>::type point2_type;
+ typedef typename model::referring_segment<point1_type const> segment1_type;
+ typedef typename model::referring_segment<point2_type const> segment2_type;
+
+
+ template <size_t Dim, typename Point, typename Box>
+ static inline bool preceding(int dir, Point const& point, Box const& box)
+ {
+ return (dir == 1 && get<Dim>(point) < get<min_corner, Dim>(box))
+ || (dir == -1 && get<Dim>(point) > get<max_corner, Dim>(box));
+ }
+
+ template <size_t Dim, typename Point, typename Box>
+ static inline bool exceeding(int dir, Point const& point, Box const& box)
+ {
+ return (dir == 1 && get<Dim>(point) > get<max_corner, Dim>(box))
+ || (dir == -1 && get<Dim>(point) < get<min_corner, Dim>(box));
+ }
+
+ template <typename Iterator, typename RangeIterator, typename Section>
+ static inline void advance_to_non_duplicate_next(Iterator& next,
+ RangeIterator const& it, Section const& section)
+ {
+ // To see where the next segments bend to, in case of touch/intersections
+ // on end points, we need (in case of degenerate/duplicate points) an extra
+ // iterator which moves to the REAL next point, so non duplicate.
+ // This needs an extra comparison (disjoint).
+ // (Note that within sections, non duplicate points are already asserted,
+ // by the sectionalize process).
+
+ // So advance to the "non duplicate next"
+ // (the check is defensive, to avoid endless loops)
+ std::size_t check = 0;
+ while(! detail::disjoint::disjoint_point_point(*it, *next)
+ && check++ < section.range_count)
+ {
+ next++;
+ }
+ }
+
+ // It is NOT possible to have section-iterators here
+ // because of the logistics of "index" (the section-iterator automatically
+ // skips to the begin-point, we loose the index or have to recalculate it)
+ // So we mimic it here
+ template <typename Range, typename Section, typename Box>
+ static inline void get_start_point_iterator(Section & section,
+ Range const& range,
+ typename boost::range_iterator<Range const>::type& it,
+ typename boost::range_iterator<Range const>::type& prev,
+ typename boost::range_iterator<Range const>::type& end,
+ int& index, int& ndi,
+ int dir, Box const& other_bounding_box)
+ {
+ it = boost::begin(range) + section.begin_index;
+ end = boost::begin(range) + section.end_index + 1;
+
+ // Mimic section-iterator:
+ // Skip to point such that section interects other box
+ prev = it++;
+ for(; it != end && preceding<0>(dir, *it, other_bounding_box);
+ prev = it++, index++, ndi++)
+ {}
+ // Go back one step because we want to start completely preceding
+ it = prev;
+ }
+};
+
+struct get_section_box
+{
+ template <typename Box, typename InputItem>
+ static inline void apply(Box& total, InputItem const& item)
+ {
+ geometry::expand(total, item.bounding_box);
+ }
+};
+
+struct ovelaps_section_box
+{
+ template <typename Box, typename InputItem>
+ static inline bool apply(Box const& box, InputItem const& item)
+ {
+ return ! detail::disjoint::disjoint_box_box(box, item.bounding_box);
+ }
+};
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct section_visitor
+{
+ int m_source_id1;
+ Geometry1 const& m_geometry1;
+ int m_source_id2;
+ Geometry2 const& m_geometry2;
+ Turns& m_turns;
+ InterruptPolicy& m_interrupt_policy;
+
+ section_visitor(int id1, Geometry1 const& g1,
+ int id2, Geometry2 const& g2,
+ Turns& turns, InterruptPolicy& ip)
+ : m_source_id1(id1), m_geometry1(g1)
+ , m_source_id2(id2), m_geometry2(g2)
+ , m_turns(turns)
+ , m_interrupt_policy(ip)
+ {}
+
+ template <typename Section>
+ inline bool apply(Section const& sec1, Section const& sec2)
+ {
+ if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box))
+ {
+ return get_turns_in_sections
+ <
+ Geometry1,
+ Geometry2,
+ Reverse1, Reverse2,
+ Section, Section,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >::apply(
+ m_source_id1, m_geometry1, sec1,
+ m_source_id2, m_geometry2, sec2,
+ false,
+ m_turns, m_interrupt_policy);
+ }
+ return true;
+ }
+
+};
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+class get_turns_generic
+{
+
+public:
+ static inline void apply(
+ int source_id1, Geometry1 const& geometry1,
+ int source_id2, Geometry2 const& geometry2,
+ Turns& turns, InterruptPolicy& interrupt_policy)
+ {
+ // First create monotonic sections...
+ typedef typename boost::range_value<Turns>::type ip_type;
+ typedef typename ip_type::point_type point_type;
+ typedef model::box<point_type> box_type;
+ typedef typename geometry::sections<box_type, 2> sections_type;
+
+ sections_type sec1, sec2;
+
+ geometry::sectionalize<Reverse1>(geometry1, sec1, 0);
+ geometry::sectionalize<Reverse2>(geometry2, sec2, 1);
+
+ // ... and then partition them, intersecting overlapping sections in visitor method
+ section_visitor
+ <
+ Geometry1, Geometry2,
+ Reverse1, Reverse2,
+ Turns, TurnPolicy, InterruptPolicy
+ > visitor(source_id1, geometry1, source_id2, geometry2, turns, interrupt_policy);
+
+ geometry::partition
+ <
+ box_type, get_section_box, ovelaps_section_box
+ >::apply(sec1, sec2, visitor);
+ }
+};
+
+
+// Get turns for a range with a box, following Cohen-Sutherland (cs) approach
+template
+<
+ typename Range, typename Box,
+ bool ReverseRange, bool ReverseBox,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns_cs
+{
+ typedef typename boost::range_value<Turns>::type turn_info;
+ typedef typename geometry::point_type<Range>::type point_type;
+ typedef typename geometry::point_type<Box>::type box_point_type;
+
+ typedef typename closeable_view
+ <
+ Range const,
+ closure<Range>::value
+ >::type cview_type;
+
+ typedef typename reversible_view
+ <
+ cview_type const,
+ ReverseRange ? iterate_reverse : iterate_forward
+ >::type view_type;
+
+ typedef typename boost::range_iterator
+ <
+ view_type const
+ >::type iterator_type;
+
+
+ static inline void apply(
+ int source_id1, Range const& range,
+ int source_id2, Box const& box,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy,
+ int multi_index = -1, int ring_index = -1)
+ {
+ if (boost::size(range) <= 1)
+ {
+ return;
+ }
+
+ boost::array<box_point_type,4> bp;
+ assign_box_corners_oriented<ReverseBox>(box, bp);
+
+ cview_type cview(range);
+ view_type view(cview);
+
+ iterator_type it = boost::begin(view);
+
+ ever_circling_iterator<iterator_type> next(
+ boost::begin(view), boost::end(view), it, true);
+ next++;
+ next++;
+
+ //bool first = true;
+
+ //char previous_side[2] = {0, 0};
+
+ int index = 0;
+
+ for (iterator_type prev = it++;
+ it != boost::end(view);
+ prev = it++, next++, index++)
+ {
+ segment_identifier seg_id(source_id1,
+ multi_index, ring_index, index);
+
+ /*if (first)
+ {
+ previous_side[0] = get_side<0>(box, *prev);
+ previous_side[1] = get_side<1>(box, *prev);
+ }
+
+ char current_side[2];
+ current_side[0] = get_side<0>(box, *it);
+ current_side[1] = get_side<1>(box, *it);
+
+ // There can NOT be intersections if
+ // 1) EITHER the two points are lying on one side of the box (! 0 && the same)
+ // 2) OR same in Y-direction
+ // 3) OR all points are inside the box (0)
+ if (! (
+ (current_side[0] != 0 && current_side[0] == previous_side[0])
+ || (current_side[1] != 0 && current_side[1] == previous_side[1])
+ || (current_side[0] == 0
+ && current_side[1] == 0
+ && previous_side[0] == 0
+ && previous_side[1] == 0)
+ )
+ )*/
+ if (true)
+ {
+ get_turns_with_box(seg_id, source_id2,
+ *prev, *it, *next,
+ bp[0], bp[1], bp[2], bp[3],
+ turns, interrupt_policy);
+ // Future performance enhancement:
+ // return if told by the interrupt policy
+ }
+ }
+ }
+
+private:
+ template<std::size_t Index, typename Point>
+ static inline int get_side(Box const& box, Point const& point)
+ {
+ // Inside -> 0
+ // Outside -> -1 (left/below) or 1 (right/above)
+ // On border -> -2 (left/lower) or 2 (right/upper)
+ // The only purpose of the value is to not be the same,
+ // and to denote if it is inside (0)
+
+ typename coordinate_type<Point>::type const& c = get<Index>(point);
+ typename coordinate_type<Box>::type const& left = get<min_corner, Index>(box);
+ typename coordinate_type<Box>::type const& right = get<max_corner, Index>(box);
+
+ if (geometry::math::equals(c, left)) return -2;
+ else if (geometry::math::equals(c, right)) return 2;
+ else if (c < left) return -1;
+ else if (c > right) return 1;
+ else return 0;
+ }
+
+ static inline void get_turns_with_box(segment_identifier const& seg_id, int source_id2,
+ // Points from a range:
+ point_type const& rp0,
+ point_type const& rp1,
+ point_type const& rp2,
+ // Points from the box
+ box_point_type const& bp0,
+ box_point_type const& bp1,
+ box_point_type const& bp2,
+ box_point_type const& bp3,
+ // Output
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
+ {
+ // Depending on code some relations can be left out
+
+ typedef typename boost::range_value<Turns>::type turn_info;
+
+ turn_info ti;
+ ti.operations[0].seg_id = seg_id;
+ ti.operations[0].other_id = ti.operations[1].seg_id;
+ ti.operations[1].other_id = seg_id;
+
+ ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 0);
+ TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2,
+ ti, std::back_inserter(turns));
+
+ ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 1);
+ TurnPolicy::apply(rp0, rp1, rp2, bp1, bp2, bp3,
+ ti, std::back_inserter(turns));
+
+ ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 2);
+ TurnPolicy::apply(rp0, rp1, rp2, bp2, bp3, bp0,
+ ti, std::back_inserter(turns));
+
+ ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 3);
+ TurnPolicy::apply(rp0, rp1, rp2, bp3, bp0, bp1,
+ ti, std::back_inserter(turns));
+
+ if (InterruptPolicy::enabled)
+ {
+ interrupt_policy.apply(turns);
+ }
+
+ }
+
+};
+
+
+template
+<
+ typename Polygon, typename Box,
+ bool Reverse, bool ReverseBox,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns_polygon_cs
+{
+ static inline void apply(
+ int source_id1, Polygon const& polygon,
+ int source_id2, Box const& box,
+ Turns& turns, InterruptPolicy& interrupt_policy,
+ int multi_index = -1)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ typedef detail::get_turns::get_turns_cs
+ <
+ ring_type, Box,
+ Reverse, ReverseBox,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ > intersector_type;
+
+ intersector_type::apply(
+ source_id1, geometry::exterior_ring(polygon),
+ source_id2, box, turns, interrupt_policy,
+ multi_index, -1);
+
+ int i = 0;
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings);
+ ++it, ++i)
+ {
+ intersector_type::apply(
+ source_id1, *it,
+ source_id2, box, turns, interrupt_policy,
+ multi_index, i);
+ }
+
+ }
+};
+
+}} // namespace detail::get_turns
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// Because this is "detail" method, and most implementations will use "generic",
+// we take the freedom to derive it from "generic".
+template
+<
+ typename GeometryTag1, typename GeometryTag2,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns
+ : detail::get_turns::get_turns_generic
+ <
+ Geometry1, Geometry2,
+ Reverse1, Reverse2,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >
+{};
+
+
+template
+<
+ typename Polygon, typename Box,
+ bool ReversePolygon, bool ReverseBox,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns
+ <
+ polygon_tag, box_tag,
+ Polygon, Box,
+ ReversePolygon, ReverseBox,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ > : detail::get_turns::get_turns_polygon_cs
+ <
+ Polygon, Box,
+ ReversePolygon, ReverseBox,
+ Turns, TurnPolicy, InterruptPolicy
+ >
+{};
+
+
+template
+<
+ typename Ring, typename Box,
+ bool ReverseRing, bool ReverseBox,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns
+ <
+ ring_tag, box_tag,
+ Ring, Box,
+ ReverseRing, ReverseBox,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ > : detail::get_turns::get_turns_cs
+ <
+ Ring, Box, ReverseRing, ReverseBox,
+ Turns, TurnPolicy, InterruptPolicy
+ >
+
+{};
+
+
+template
+<
+ typename GeometryTag1, typename GeometryTag2,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns_reversed
+{
+ static inline void apply(
+ int source_id1, Geometry1 const& g1,
+ int source_id2, Geometry2 const& g2,
+ Turns& turns, InterruptPolicy& interrupt_policy)
+ {
+ get_turns
+ <
+ GeometryTag2, GeometryTag1,
+ Geometry2, Geometry1,
+ Reverse2, Reverse1,
+ Turns, TurnPolicy,
+ InterruptPolicy
+ >::apply(source_id2, g2, source_id1, g1, turns, interrupt_policy);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+\brief \brief_calc2{turn points}
+\ingroup overlay
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Turns type of turn-container (e.g. vector of "intersection/turn point"'s)
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param turns container which will contain turn points
+\param interrupt_policy policy determining if process is stopped
+ when intersection is found
+ */
+template
+<
+ bool Reverse1, bool Reverse2,
+ typename AssignPolicy,
+ typename Geometry1,
+ typename Geometry2,
+ typename Turns,
+ typename InterruptPolicy
+>
+inline void get_turns(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
+{
+ concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
+
+ typedef typename strategy_intersection
+ <
+ typename cs_tag<Geometry1>::type,
+ Geometry1,
+ Geometry2,
+ typename boost::range_value<Turns>::type
+ >::segment_intersection_strategy_type segment_intersection_strategy_type;
+
+ typedef detail::overlay::get_turn_info
+ <
+ typename point_type<Geometry1>::type,
+ typename point_type<Geometry2>::type,
+ typename boost::range_value<Turns>::type,
+ AssignPolicy
+ > TurnPolicy;
+
+ boost::mpl::if_c
+ <
+ reverse_dispatch<Geometry1, Geometry2>::type::value,
+ dispatch::get_turns_reversed
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1, Geometry2,
+ Reverse1, Reverse2,
+ Turns, TurnPolicy,
+ InterruptPolicy
+ >,
+ dispatch::get_turns
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1, Geometry2,
+ Reverse1, Reverse2,
+ Turns, TurnPolicy,
+ InterruptPolicy
+ >
+ >::type::apply(
+ 0, geometry1,
+ 1, geometry2,
+ turns, interrupt_policy);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp b/src/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp
new file mode 100644
index 0000000..1e878ca
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp
@@ -0,0 +1,672 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_TANGENCIES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_TANGENCIES_HPP
+
+#include <algorithm>
+
+#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+
+#include <boost/geometry/geometries/segment.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+template
+<
+ typename TurnPoints,
+ typename Indexed,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2,
+ typename Strategy
+>
+struct sort_in_cluster
+{
+ inline sort_in_cluster(TurnPoints const& turn_points
+ , Geometry1 const& geometry1
+ , Geometry2 const& geometry2
+ , Strategy const& strategy)
+ : m_turn_points(turn_points)
+ , m_geometry1(geometry1)
+ , m_geometry2(geometry2)
+ , m_strategy(strategy)
+ {}
+
+private :
+
+ TurnPoints const& m_turn_points;
+ Geometry1 const& m_geometry1;
+ Geometry2 const& m_geometry2;
+ Strategy const& m_strategy;
+
+ typedef typename Indexed::type turn_operation_type;
+ typedef typename geometry::point_type<Geometry1>::type point_type;
+ typedef model::referring_segment<point_type const> segment_type;
+
+ // Determine how p/r and p/s are located.
+ template <typename P>
+ static inline void overlap_info(P const& pi, P const& pj,
+ P const& ri, P const& rj,
+ P const& si, P const& sj,
+ bool& pr_overlap, bool& ps_overlap, bool& rs_overlap)
+ {
+ // Determine how p/r and p/s are located.
+ // One of them is coming from opposite direction.
+
+ typedef strategy::intersection::relate_cartesian_segments
+ <
+ policies::relate::segments_intersection_points
+ <
+ segment_type,
+ segment_type,
+ segment_intersection_points<point_type>
+ >
+ > policy;
+
+ segment_type p(pi, pj);
+ segment_type r(ri, rj);
+ segment_type s(si, sj);
+
+ // Get the intersection point (or two points)
+ segment_intersection_points<point_type> pr = policy::apply(p, r);
+ segment_intersection_points<point_type> ps = policy::apply(p, s);
+ segment_intersection_points<point_type> rs = policy::apply(r, s);
+
+ // Check on overlap
+ pr_overlap = pr.count == 2;
+ ps_overlap = ps.count == 2;
+ rs_overlap = rs.count == 2;
+ }
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ inline void debug_consider(int order, Indexed const& left,
+ Indexed const& right, std::string const& header,
+ bool skip = true,
+ std::string const& extra = "", bool ret = false
+ ) const
+ {
+ if (skip) return;
+
+ point_type pi, pj, ri, rj, si, sj;
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ left.subject.seg_id,
+ pi, pj);
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ left.subject.other_id,
+ ri, rj);
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ right.subject.other_id,
+ si, sj);
+
+ bool prc = false, psc = false, rsc = false;
+ overlap_info(pi, pj, ri, rj, si, sj, prc, psc, rsc);
+
+ int const side_ri_p = m_strategy.apply(pi, pj, ri);
+ int const side_rj_p = m_strategy.apply(pi, pj, rj);
+ int const side_si_p = m_strategy.apply(pi, pj, si);
+ int const side_sj_p = m_strategy.apply(pi, pj, sj);
+ int const side_si_r = m_strategy.apply(ri, rj, si);
+ int const side_sj_r = m_strategy.apply(ri, rj, sj);
+
+ std::cout << "Case: " << header << " for " << left.index << " / " << right.index << std::endl;
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH_MORE
+ std::cout << " Segment p:" << geometry::wkt(pi) << " .. " << geometry::wkt(pj) << std::endl;
+ std::cout << " Segment r:" << geometry::wkt(ri) << " .. " << geometry::wkt(rj) << std::endl;
+ std::cout << " Segment s:" << geometry::wkt(si) << " .. " << geometry::wkt(sj) << std::endl;
+
+ std::cout << " r//p: " << side_ri_p << " / " << side_rj_p << std::endl;
+ std::cout << " s//p: " << side_si_p << " / " << side_sj_p << std::endl;
+ std::cout << " s//r: " << side_si_r << " / " << side_sj_r << std::endl;
+#endif
+
+ std::cout << header
+ //<< " order: " << order
+ << " ops: " << operation_char(left.subject.operation)
+ << "/" << operation_char(right.subject.operation)
+ << " ri//p: " << side_ri_p
+ << " si//p: " << side_si_p
+ << " si//r: " << side_si_r
+ << " cnts: " << int(prc) << "," << int(psc) << "," << int(rsc)
+ //<< " idx: " << left.index << "/" << right.index
+ ;
+
+ if (! extra.empty())
+ {
+ std::cout << " " << extra << " " << (ret ? "true" : "false");
+ }
+ std::cout << std::endl;
+ }
+#else
+ inline void debug_consider(int, Indexed const& ,
+ Indexed const& , std::string const& ,
+ bool = true,
+ std::string const& = "", bool = false
+ ) const
+ {}
+#endif
+
+
+ // ux/ux
+ inline bool consider_ux_ux(Indexed const& left,
+ Indexed const& right
+ , std::string const& // header
+ ) const
+ {
+ bool ret = left.index < right.index;
+
+ // In combination of u/x, x/u: take first union, then blocked.
+ // Solves #88, #61, #56, #80
+ if (left.subject.operation == operation_union
+ && right.subject.operation == operation_blocked)
+ {
+ ret = true;
+ }
+ else if (left.subject.operation == operation_blocked
+ && right.subject.operation == operation_union)
+ {
+ ret = false;
+ }
+ else
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << "ux/ux unhandled" << std::endl;
+#endif
+ }
+
+ //debug_consider(0, left, right, header, false, "-> return ", ret);
+
+ return ret;
+ }
+
+ inline bool consider_iu_ux(Indexed const& left,
+ Indexed const& right,
+ int order // 1: iu first, -1: ux first
+ , std::string const& // header
+ ) const
+ {
+ bool ret = false;
+
+ if (left.subject.operation == operation_union
+ && right.subject.operation == operation_union)
+ {
+ ret = order == 1;
+ }
+ else if (left.subject.operation == operation_union
+ && right.subject.operation == operation_blocked)
+ {
+ ret = true;
+ }
+ else if (right.subject.operation == operation_union
+ && left.subject.operation == operation_blocked)
+ {
+ ret = false;
+ }
+ else if (left.subject.operation == operation_union)
+ {
+ ret = true;
+ }
+ else if (right.subject.operation == operation_union)
+ {
+ ret = false;
+ }
+ else
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ // this still happens in the traverse.cpp test
+ std::cout << " iu/ux unhandled" << std::endl;
+#endif
+ ret = order == 1;
+ }
+
+ //debug_consider(0, left, right, header, false, "-> return", ret);
+ return ret;
+ }
+
+ inline bool consider_iu_ix(Indexed const& left,
+ Indexed const& right,
+ int order // 1: iu first, -1: ix first
+ , std::string const& // header
+ ) const
+ {
+ //debug_consider(order, left, right, header, false, "iu/ix");
+
+ return left.subject.operation == operation_intersection
+ && right.subject.operation == operation_intersection ? order == 1
+ : left.subject.operation == operation_intersection ? false
+ : right.subject.operation == operation_intersection ? true
+ : order == 1;
+ }
+
+
+ inline bool consider_iu_iu(Indexed const& left, Indexed const& right,
+ std::string const& header) const
+ {
+ //debug_consider(0, left, right, header);
+
+ // In general, order it like "union, intersection".
+ if (left.subject.operation == operation_intersection
+ && right.subject.operation == operation_union)
+ {
+ //debug_consider(0, left, right, header, false, "i,u", false);
+ return false;
+ }
+ else if (left.subject.operation == operation_union
+ && right.subject.operation == operation_intersection)
+ {
+ //debug_consider(0, left, right, header, false, "u,i", true);
+ return true;
+ }
+
+ point_type pi, pj, ri, rj, si, sj;
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ left.subject.seg_id,
+ pi, pj);
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ left.subject.other_id,
+ ri, rj);
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ right.subject.other_id,
+ si, sj);
+
+ int const side_ri_p = m_strategy.apply(pi, pj, ri);
+ int const side_si_p = m_strategy.apply(pi, pj, si);
+ int const side_si_r = m_strategy.apply(ri, rj, si);
+
+ // Both located at same side (#58, pie_21_7_21_0_3)
+ if (side_ri_p * side_si_p == 1 && side_si_r != 0)
+ {
+ // Take the most left one
+ if (left.subject.operation == operation_union
+ && right.subject.operation == operation_union)
+ {
+ bool ret = side_si_r == 1;
+ //debug_consider(0, left, right, header, false, "same side", ret);
+ return ret;
+ }
+ }
+
+
+ // Coming from opposite sides (#59, #99)
+ if (side_ri_p * side_si_p == -1)
+ {
+ bool ret = false;
+
+ {
+ ret = side_ri_p == 1; // #100
+ debug_consider(0, left, right, header, false, "opp.", ret);
+ return ret;
+ }
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << " iu/iu coming from opposite unhandled" << std::endl;
+#endif
+ }
+
+ // We need EXTRA information here: are p/r/s overlapping?
+ bool pr_ov = false, ps_ov = false, rs_ov = false;
+ overlap_info(pi, pj, ri, rj, si, sj, pr_ov, ps_ov, rs_ov);
+
+ // One coming from right (#83,#90)
+ // One coming from left (#90, #94, #95)
+ if (side_si_r != 0 && (side_ri_p != 0 || side_si_p != 0))
+ {
+ bool ret = false;
+
+ if (pr_ov || ps_ov)
+ {
+ int r = side_ri_p != 0 ? side_ri_p : side_si_p;
+ ret = r * side_si_r == 1;
+ }
+ else
+ {
+ ret = side_si_r == 1;
+ }
+
+ debug_consider(0, left, right, header, false, "left or right", ret);
+ return ret;
+ }
+
+ // All aligned (#92, #96)
+ if (side_ri_p == 0 && side_si_p == 0 && side_si_r == 0)
+ {
+ // One of them is coming from opposite direction.
+
+ // Take the one NOT overlapping
+ bool ret = false;
+ bool found = false;
+ if (pr_ov && ! ps_ov)
+ {
+ ret = true;
+ found = true;
+ }
+ else if (!pr_ov && ps_ov)
+ {
+ ret = false;
+ found = true;
+ }
+
+ debug_consider(0, left, right, header, false, "aligned", ret);
+ if (found)
+ {
+ return ret;
+ }
+ }
+
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << " iu/iu unhandled" << std::endl;
+ debug_consider(0, left, right, header, false, "unhandled", left.index < right.index);
+#endif
+ return left.index < right.index;
+ }
+
+ inline bool consider_ii(Indexed const& left, Indexed const& right,
+ std::string const& header) const
+ {
+ debug_consider(0, left, right, header);
+
+ point_type pi, pj, ri, rj, si, sj;
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ left.subject.seg_id,
+ pi, pj);
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ left.subject.other_id,
+ ri, rj);
+ geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
+ right.subject.other_id,
+ si, sj);
+
+ int const side_ri_p = m_strategy.apply(pi, pj, ri);
+ int const side_si_p = m_strategy.apply(pi, pj, si);
+
+ // Two other points are (mostly) lying both right of the considered segment
+ // Take the most left one
+ int const side_si_r = m_strategy.apply(ri, rj, si);
+ if (side_ri_p == -1
+ && side_si_p == -1
+ && side_si_r != 0)
+ {
+ bool const ret = side_si_r != 1;
+ return ret;
+ }
+ return left.index < right.index;
+ }
+
+
+public :
+ inline bool operator()(Indexed const& left, Indexed const& right) const
+ {
+ bool const default_order = left.index < right.index;
+
+ if ((m_turn_points[left.index].discarded || left.discarded)
+ && (m_turn_points[right.index].discarded || right.discarded))
+ {
+ return default_order;
+ }
+ else if (m_turn_points[left.index].discarded || left.discarded)
+ {
+ // Be careful to sort discarded first, then all others
+ return true;
+ }
+ else if (m_turn_points[right.index].discarded || right.discarded)
+ {
+ // See above so return false here such that right (discarded)
+ // is sorted before left (not discarded)
+ return false;
+ }
+ else if (m_turn_points[left.index].combination(operation_blocked, operation_union)
+ && m_turn_points[right.index].combination(operation_blocked, operation_union))
+ {
+ // ux/ux
+ return consider_ux_ux(left, right, "ux/ux");
+ }
+ else if (m_turn_points[left.index].both(operation_union)
+ && m_turn_points[right.index].both(operation_union))
+ {
+ // uu/uu, Order is arbitrary
+ // Note: uu/uu is discarded now before so this point will
+ // not be reached.
+ return default_order;
+ }
+ else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
+ && m_turn_points[right.index].combination(operation_intersection, operation_union))
+ {
+ return consider_iu_iu(left, right, "iu/iu");
+ }
+ else if (m_turn_points[left.index].both(operation_intersection)
+ && m_turn_points[right.index].both(operation_intersection))
+ {
+ return consider_ii(left, right, "ii/ii");
+ }
+ else if (m_turn_points[left.index].combination(operation_union, operation_blocked)
+ && m_turn_points[right.index].combination(operation_intersection, operation_union))
+ {
+ return consider_iu_ux(left, right, -1, "ux/iu");
+ }
+ else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
+ && m_turn_points[right.index].combination(operation_union, operation_blocked))
+ {
+ return consider_iu_ux(left, right, 1, "iu/ux");
+ }
+ else if (m_turn_points[left.index].combination(operation_intersection, operation_blocked)
+ && m_turn_points[right.index].combination(operation_intersection, operation_union))
+ {
+ return consider_iu_ix(left, right, 1, "ix/iu");
+ }
+ else if (m_turn_points[left.index].combination(operation_intersection, operation_union)
+ && m_turn_points[right.index].combination(operation_intersection, operation_blocked))
+ {
+ return consider_iu_ix(left, right, -1, "iu/ix");
+ }
+ else if (m_turn_points[left.index].method != method_equal
+ && m_turn_points[right.index].method == method_equal
+ )
+ {
+ // If one of them was EQUAL or CONTINUES, it should always come first
+ return false;
+ }
+ else if (m_turn_points[left.index].method == method_equal
+ && m_turn_points[right.index].method != method_equal
+ )
+ {
+ return true;
+ }
+
+ // Now we have no clue how to sort.
+
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ std::cout << " Consider: " << operation_char(m_turn_points[left.index].operations[0].operation)
+ << operation_char(m_turn_points[left.index].operations[1].operation)
+ << "/" << operation_char(m_turn_points[right.index].operations[0].operation)
+ << operation_char(m_turn_points[right.index].operations[1].operation)
+ << " " << " Take " << left.index << " < " << right.index
+ << std::cout;
+#endif
+
+ return default_order;
+ }
+};
+
+
+
+template
+<
+ typename IndexType,
+ typename Iterator,
+ typename TurnPoints,
+ typename Geometry1,
+ typename Geometry2,
+ typename Strategy
+>
+inline void inspect_cluster(Iterator begin_cluster, Iterator end_cluster,
+ TurnPoints& turn_points,
+ operation_type ,
+ Geometry1 const& , Geometry2 const& ,
+ Strategy const& )
+{
+ int count = 0;
+
+ // Make an analysis about all occuring cases here.
+ std::map<std::pair<operation_type, operation_type>, int> inspection;
+ for (Iterator it = begin_cluster; it != end_cluster; ++it)
+ {
+ operation_type first = turn_points[it->index].operations[0].operation;
+ operation_type second = turn_points[it->index].operations[1].operation;
+ if (first > second)
+ {
+ std::swap(first, second);
+ }
+ inspection[std::make_pair(first, second)]++;
+ count++;
+ }
+
+
+ bool keep_cc = false;
+
+ // Decide about which is going to be discarded here.
+ if (inspection[std::make_pair(operation_union, operation_union)] == 1
+ && inspection[std::make_pair(operation_continue, operation_continue)] == 1)
+ {
+ // In case of uu/cc, discard the uu, that indicates a tangency and
+ // inclusion would disturb the (e.g.) cc-cc-cc ordering
+ // NOTE: uu is now discarded anyhow.
+ keep_cc = true;
+ }
+ else if (count == 2
+ && inspection[std::make_pair(operation_intersection, operation_intersection)] == 1
+ && inspection[std::make_pair(operation_union, operation_intersection)] == 1)
+ {
+ // In case of ii/iu, discard the iu. The ii should always be visited,
+ // Because (in case of not discarding iu) correctly ordering of ii/iu appears impossible
+ for (Iterator it = begin_cluster; it != end_cluster; ++it)
+ {
+ if (turn_points[it->index].combination(operation_intersection, operation_union))
+ {
+ it->discarded = true;
+ }
+ }
+ }
+
+ // Discard any continue turn, unless it is the only thing left
+ // (necessary to avoid cc-only rings, all being discarded
+ // e.g. traversal case #75)
+ int nd_count= 0, cc_count = 0;
+ for (Iterator it = begin_cluster; it != end_cluster; ++it)
+ {
+ if (! it->discarded)
+ {
+ nd_count++;
+ if (turn_points[it->index].both(operation_continue))
+ {
+ cc_count++;
+ }
+ }
+ }
+
+ if (nd_count == cc_count)
+ {
+ keep_cc = true;
+ }
+
+ if (! keep_cc)
+ {
+ for (Iterator it = begin_cluster; it != end_cluster; ++it)
+ {
+ if (turn_points[it->index].both(operation_continue))
+ {
+ it->discarded = true;
+ }
+ }
+ }
+}
+
+
+template
+<
+ typename IndexType,
+ bool Reverse1, bool Reverse2,
+ typename Iterator,
+ typename TurnPoints,
+ typename Geometry1,
+ typename Geometry2,
+ typename Strategy
+>
+inline void handle_cluster(Iterator begin_cluster, Iterator end_cluster,
+ TurnPoints& turn_points,
+ operation_type for_operation,
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ // First inspect and (possibly) discard rows
+ inspect_cluster<IndexType>(begin_cluster, end_cluster, turn_points,
+ for_operation, geometry1, geometry2, strategy);
+
+
+ // Then sort this range (discard rows will be ordered first and will be removed in enrich_assign)
+ std::sort(begin_cluster, end_cluster,
+ sort_in_cluster
+ <
+ TurnPoints,
+ IndexType,
+ Geometry1, Geometry2,
+ Reverse1, Reverse2,
+ Strategy
+ >(turn_points, geometry1, geometry2, strategy));
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
+ typedef typename IndexType::type operations_type;
+ operations_type const& op = turn_points[begin_cluster->index].operations[begin_cluster->operation_index];
+ std::cout << "Clustered points on equal distance " << op.enriched.distance << std::endl;
+ std::cout << "->Indexes ";
+
+ for (Iterator it = begin_cluster; it != end_cluster; ++it)
+ {
+ std::cout << " " << it->index;
+ }
+ std::cout << std::endl << "->Methods: ";
+ for (Iterator it = begin_cluster; it != end_cluster; ++it)
+ {
+ std::cout << " " << method_char(turn_points[it->index].method);
+ }
+ std::cout << std::endl << "->Operations: ";
+ for (Iterator it = begin_cluster; it != end_cluster; ++it)
+ {
+ std::cout << " " << operation_char(turn_points[it->index].operations[0].operation)
+ << operation_char(turn_points[it->index].operations[1].operation);
+ }
+ std::cout << std::endl << "->Discarded: ";
+ for (Iterator it = begin_cluster; it != end_cluster; ++it)
+ {
+ std::cout << " " << (it->discarded ? "true" : "false");
+ }
+ std::cout << std::endl;
+ //<< "\tOn segments: " << prev_op.seg_id << " / " << prev_op.other_id
+ //<< " and " << op.seg_id << " / " << op.other_id
+ //<< geometry::distance(turn_points[prev->index].point, turn_points[it->index].point)
+#endif
+
+}
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_HANDLE_TANGENCIES_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/src/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
new file mode 100644
index 0000000..8bca790
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp
@@ -0,0 +1,690 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
+
+
+#include <cstddef>
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <boost/geometry/core/is_areal.hpp>
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/reverse_dispatch.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+#include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/follow.hpp>
+#include <boost/geometry/views/segment_view.hpp>
+
+#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
+#include <boost/foreach.hpp>
+#endif
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection
+{
+
+template
+<
+ typename Segment1, typename Segment2,
+ typename OutputIterator, typename PointOut,
+ typename Strategy
+>
+struct intersection_segment_segment_point
+{
+ static inline OutputIterator apply(Segment1 const& segment1,
+ Segment2 const& segment2, OutputIterator out,
+ Strategy const& )
+ {
+ typedef typename point_type<PointOut>::type point_type;
+
+ // Get the intersection point (or two points)
+ segment_intersection_points<point_type> is
+ = strategy::intersection::relate_cartesian_segments
+ <
+ policies::relate::segments_intersection_points
+ <
+ Segment1,
+ Segment2,
+ segment_intersection_points<point_type>
+ >
+ >::apply(segment1, segment2);
+
+ for (std::size_t i = 0; i < is.count; i++)
+ {
+ PointOut p;
+ geometry::convert(is.intersections[i], p);
+ *out++ = p;
+ }
+ return out;
+ }
+};
+
+template
+<
+ typename Linestring1, typename Linestring2,
+ typename OutputIterator, typename PointOut,
+ typename Strategy
+>
+struct intersection_linestring_linestring_point
+{
+ static inline OutputIterator apply(Linestring1 const& linestring1,
+ Linestring2 const& linestring2, OutputIterator out,
+ Strategy const& )
+ {
+ typedef typename point_type<PointOut>::type point_type;
+
+ typedef detail::overlay::turn_info<point_type> turn_info;
+ std::deque<turn_info> turns;
+
+ geometry::get_intersection_points(linestring1, linestring2, turns);
+
+ for (typename boost::range_iterator<std::deque<turn_info> const>::type
+ it = boost::begin(turns); it != boost::end(turns); ++it)
+ {
+ PointOut p;
+ geometry::convert(it->point, p);
+ *out++ = p;
+ }
+ return out;
+ }
+};
+
+/*!
+\brief Version of linestring with an areal feature (polygon or multipolygon)
+*/
+template
+<
+ typename LineString, typename Areal,
+ bool ReverseAreal,
+ typename OutputIterator, typename LineStringOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_of_linestring_with_areal
+{
+ typedef detail::overlay::follow
+ <
+ LineStringOut,
+ LineString,
+ Areal,
+ OverlayType
+ > follower;
+
+#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
+ template <typename Turn, typename Operation>
+ static inline void debug_follow(Turn const& turn, Operation op,
+ int index)
+ {
+ std::cout << index
+ << " at " << op.seg_id
+ << " meth: " << method_char(turn.method)
+ << " op: " << operation_char(op.operation)
+ << " vis: " << visited_char(op.visited)
+ << " of: " << operation_char(turn.operations[0].operation)
+ << operation_char(turn.operations[1].operation)
+ << " " << geometry::wkt(turn.point)
+ << std::endl;
+ }
+#endif
+
+ static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
+ OutputIterator out,
+ Strategy const& )
+ {
+ if (boost::size(linestring) == 0)
+ {
+ return out;
+ }
+
+ typedef typename point_type<LineStringOut>::type point_type;
+
+ typedef detail::overlay::traversal_turn_info<point_type> turn_info;
+ std::deque<turn_info> turns;
+
+ detail::get_turns::no_interrupt_policy policy;
+ geometry::get_turns
+ <
+ false,
+ (OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
+ detail::overlay::calculate_distance_policy
+ >(linestring, areal, turns, policy);
+
+ if (turns.empty())
+ {
+ // No intersection points, it is either completely
+ // inside (interior + borders)
+ // or completely outside
+
+ // Use border point (on a segment) to check this
+ // (because turn points might skip some cases)
+ point_type border_point;
+ if (! geometry::point_on_border(border_point, linestring, true))
+ {
+ return out;
+ }
+
+
+ if (follower::included(border_point, areal))
+ {
+ LineStringOut copy;
+ geometry::convert(linestring, copy);
+ *out++ = copy;
+ }
+ return out;
+ }
+
+#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
+ int index = 0;
+ BOOST_FOREACH(turn_info const& turn, turns)
+ {
+ debug_follow(turn, turn.operations[0], index++);
+ }
+#endif
+
+ return follower::apply
+ (
+ linestring, areal,
+ geometry::detail::overlay::operation_intersection,
+ turns, out
+ );
+ }
+};
+
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ // tag dispatching:
+ typename TagIn1, typename TagIn2, typename TagOut,
+ // orientation
+ // metafunction finetuning helpers:
+ bool Areal1, bool Areal2, bool ArealOut,
+ // real types
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES_OR_ORIENTATIONS
+ , (types<Geometry1, Geometry2, GeometryOut>)
+ );
+};
+
+
+template
+<
+ typename TagIn1, typename TagIn2, typename TagOut,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ TagIn1, TagIn2, TagOut,
+ true, true, true,
+ Geometry1, Geometry2,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::overlay::overlay
+ <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
+{};
+
+
+// Any areal type with box:
+template
+<
+ typename TagIn, typename TagOut,
+ typename Geometry, typename Box,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator,
+ typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ TagIn, box_tag, TagOut,
+ true, true, true,
+ Geometry, Box,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::overlay::overlay
+ <Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, OverlayType, Strategy>
+{};
+
+
+template
+<
+ typename Segment1, typename Segment2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ segment_tag, segment_tag, point_tag,
+ false, false, false,
+ Segment1, Segment2,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType, Strategy
+ > : detail::intersection::intersection_segment_segment_point
+ <
+ Segment1, Segment2,
+ OutputIterator, GeometryOut,
+ Strategy
+ >
+{};
+
+
+template
+<
+ typename Linestring1, typename Linestring2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ linestring_tag, linestring_tag, point_tag,
+ false, false, false,
+ Linestring1, Linestring2,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType, Strategy
+ > : detail::intersection::intersection_linestring_linestring_point
+ <
+ Linestring1, Linestring2,
+ OutputIterator, GeometryOut,
+ Strategy
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename Box,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ linestring_tag, box_tag, linestring_tag,
+ false, true, false,
+ Linestring, Box,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{
+ static inline OutputIterator apply(Linestring const& linestring,
+ Box const& box, OutputIterator out, Strategy const& )
+ {
+ typedef typename point_type<GeometryOut>::type point_type;
+ strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
+ return detail::intersection::clip_range_with_box
+ <GeometryOut>(box, linestring, out, lb_strategy);
+ }
+};
+
+
+template
+<
+ typename Linestring, typename Polygon,
+ bool ReverseLinestring, bool ReversePolygon, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ linestring_tag, polygon_tag, linestring_tag,
+ false, true, false,
+ Linestring, Polygon,
+ ReverseLinestring, ReversePolygon, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_of_linestring_with_areal
+ <
+ Linestring, Polygon,
+ ReversePolygon,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename Ring,
+ bool ReverseLinestring, bool ReverseRing, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ linestring_tag, ring_tag, linestring_tag,
+ false, true, false,
+ Linestring, Ring,
+ ReverseLinestring, ReverseRing, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_of_linestring_with_areal
+ <
+ Linestring, Ring,
+ ReverseRing,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{};
+
+template
+<
+ typename Segment, typename Box,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ segment_tag, box_tag, linestring_tag,
+ false, true, false,
+ Segment, Box,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{
+ static inline OutputIterator apply(Segment const& segment,
+ Box const& box, OutputIterator out, Strategy const& )
+ {
+ geometry::segment_view<Segment> range(segment);
+
+ typedef typename point_type<GeometryOut>::type point_type;
+ strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
+ return detail::intersection::clip_range_with_box
+ <GeometryOut>(box, range, out, lb_strategy);
+ }
+};
+
+template
+<
+ typename Tag1, typename Tag2,
+ bool Areal1, bool Areal2,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename PointOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ Tag1, Tag2, point_tag,
+ Areal1, Areal2, false,
+ Geometry1, Geometry2,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, PointOut,
+ OverlayType,
+ Strategy
+ >
+{
+ static inline OutputIterator apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2, OutputIterator out, Strategy const& )
+ {
+
+ typedef detail::overlay::turn_info<PointOut> turn_info;
+ std::vector<turn_info> turns;
+
+ detail::get_turns::no_interrupt_policy policy;
+ geometry::get_turns
+ <
+ false, false, detail::overlay::assign_null_policy
+ >(geometry1, geometry2, turns, policy);
+ for (typename std::vector<turn_info>::const_iterator it
+ = turns.begin(); it != turns.end(); ++it)
+ {
+ *out++ = it->point;
+ }
+
+ return out;
+ }
+};
+
+
+template
+<
+ typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
+ bool Areal1, bool Areal2, bool ArealOut,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert_reversed
+{
+ static inline OutputIterator apply(Geometry1 const& g1,
+ Geometry2 const& g2, OutputIterator out,
+ Strategy const& strategy)
+ {
+ return intersection_insert
+ <
+ GeometryTag2, GeometryTag1, GeometryTag3,
+ Areal2, Areal1, ArealOut,
+ Geometry2, Geometry1,
+ Reverse2, Reverse1, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >::apply(g2, g1, out, strategy);
+ }
+};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection
+{
+
+
+template
+<
+ typename GeometryOut,
+ bool ReverseSecond,
+ overlay_type OverlayType,
+ typename Geometry1, typename Geometry2,
+ typename OutputIterator,
+ typename Strategy
+>
+inline OutputIterator insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out,
+ Strategy const& strategy)
+{
+ return boost::mpl::if_c
+ <
+ geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
+ geometry::dispatch::intersection_insert_reversed
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type,
+ typename geometry::tag<GeometryOut>::type,
+ geometry::is_areal<Geometry1>::value,
+ geometry::is_areal<Geometry2>::value,
+ geometry::is_areal<GeometryOut>::value,
+ Geometry1, Geometry2,
+ overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
+ overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >,
+ geometry::dispatch::intersection_insert
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type,
+ typename geometry::tag<GeometryOut>::type,
+ geometry::is_areal<Geometry1>::value,
+ geometry::is_areal<Geometry2>::value,
+ geometry::is_areal<GeometryOut>::value,
+ Geometry1, Geometry2,
+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
+ geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+ >::type::apply(geometry1, geometry2, out, strategy);
+}
+
+
+/*!
+\brief \brief_calc2{intersection} \brief_strategy
+\ingroup intersection
+\details \details_calc2{intersection_insert, spatial set theoretic intersection}
+ \brief_strategy. \details_insert{intersection}
+\tparam GeometryOut \tparam_geometry{\p_l_or_c}
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam OutputIterator \tparam_out{\p_l_or_c}
+\tparam Strategy \tparam_strategy_overlay
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param out \param_out{intersection}
+\param strategy \param_strategy{intersection}
+\return \return_out
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/intersection.qbk]}
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator,
+ typename Strategy
+>
+inline OutputIterator intersection_insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out,
+ Strategy const& strategy)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ return detail::intersection::insert
+ <
+ GeometryOut, false, overlay_intersection
+ >(geometry1, geometry2, out, strategy);
+}
+
+
+/*!
+\brief \brief_calc2{intersection}
+\ingroup intersection
+\details \details_calc2{intersection_insert, spatial set theoretic intersection}.
+ \details_insert{intersection}
+\tparam GeometryOut \tparam_geometry{\p_l_or_c}
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam OutputIterator \tparam_out{\p_l_or_c}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param out \param_out{intersection}
+\return \return_out
+
+\qbk{[include reference/algorithms/intersection.qbk]}
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator
+>
+inline OutputIterator intersection_insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ typedef strategy_intersection
+ <
+ typename cs_tag<GeometryOut>::type,
+ Geometry1,
+ Geometry2,
+ typename geometry::point_type<GeometryOut>::type
+ > strategy;
+
+ return intersection_insert<GeometryOut>(geometry1, geometry2, out,
+ strategy());
+}
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/overlay.hpp b/src/boost/geometry/algorithms/detail/overlay/overlay.hpp
new file mode 100644
index 0000000..41665e0
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/overlay.hpp
@@ -0,0 +1,301 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP
+
+
+#include <deque>
+#include <map>
+
+#include <boost/range.hpp>
+#include <boost/mpl/assert.hpp>
+
+
+#include <boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp>
+#include <boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp>
+#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
+#include <boost/geometry/algorithms/detail/overlay/traverse.hpp>
+#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+
+
+#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/reverse.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/add_rings.hpp>
+#include <boost/geometry/algorithms/detail/overlay/assign_parents.hpp>
+#include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
+#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
+# include <boost/geometry/io/dsv/write.hpp>
+#endif
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+// Skip for assemble process
+template <typename TurnInfo>
+inline bool skip(TurnInfo const& turn_info)
+{
+ return (turn_info.discarded || turn_info.both(operation_union))
+ && ! turn_info.any_blocked()
+ && ! turn_info.both(operation_intersection)
+ ;
+}
+
+
+template <typename TurnPoints, typename Map>
+inline void map_turns(Map& map, TurnPoints const& turn_points)
+{
+ typedef typename boost::range_value<TurnPoints>::type turn_point_type;
+ typedef typename turn_point_type::container_type container_type;
+
+ int index = 0;
+ for (typename boost::range_iterator<TurnPoints const>::type
+ it = boost::begin(turn_points);
+ it != boost::end(turn_points);
+ ++it, ++index)
+ {
+ if (! skip(*it))
+ {
+ int op_index = 0;
+ for (typename boost::range_iterator<container_type const>::type
+ op_it = boost::begin(it->operations);
+ op_it != boost::end(it->operations);
+ ++op_it, ++op_index)
+ {
+ ring_identifier ring_id
+ (
+ op_it->seg_id.source_index,
+ op_it->seg_id.multi_index,
+ op_it->seg_id.ring_index
+ );
+ map[ring_id]++;
+ }
+ }
+ }
+}
+
+
+template
+<
+ typename GeometryOut, overlay_type Direction, bool ReverseOut,
+ typename Geometry1, typename Geometry2,
+ typename OutputIterator
+>
+inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out)
+{
+ typedef std::deque
+ <
+ typename geometry::ring_type<GeometryOut>::type
+ > ring_container_type;
+
+ typedef ring_properties<typename geometry::point_type<Geometry1>::type> properties;
+
+ // Union: return either of them
+ // Intersection: return nothing
+ // Difference: return first of them
+ if (Direction == overlay_intersection
+ || (Direction == overlay_difference
+ && geometry::num_points(geometry1) == 0))
+ {
+ return out;
+ }
+
+ std::map<ring_identifier, int> empty;
+ std::map<ring_identifier, properties> all_of_one_of_them;
+
+ select_rings<Direction>(geometry1, geometry2, empty, all_of_one_of_them, false);
+ ring_container_type rings;
+ assign_parents(geometry1, geometry2, rings, all_of_one_of_them);
+ return add_rings<GeometryOut>(all_of_one_of_them, geometry1, geometry2, rings, out);
+}
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type Direction,
+ typename Strategy
+>
+struct overlay
+{
+ static inline OutputIterator apply(
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ OutputIterator out,
+ Strategy const& )
+ {
+ if (geometry::num_points(geometry1) == 0
+ && geometry::num_points(geometry2) == 0)
+ {
+ return out;
+ }
+
+ if (geometry::num_points(geometry1) == 0
+ || geometry::num_points(geometry2) == 0)
+ {
+ return return_if_one_input_is_empty
+ <
+ GeometryOut, Direction, ReverseOut
+ >(geometry1, geometry2, out);
+ }
+
+ typedef typename geometry::point_type<GeometryOut>::type point_type;
+ typedef detail::overlay::traversal_turn_info<point_type> turn_info;
+ typedef std::deque<turn_info> container_type;
+
+ typedef std::deque
+ <
+ typename geometry::ring_type<GeometryOut>::type
+ > ring_container_type;
+
+ container_type turn_points;
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ boost::timer timer;
+#endif
+
+#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
+std::cout << "get turns" << std::endl;
+#endif
+ detail::get_turns::no_interrupt_policy policy;
+ geometry::get_turns
+ <
+ Reverse1, Reverse2,
+ detail::overlay::calculate_distance_policy
+ >(geometry1, geometry2, turn_points, policy);
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << "get_turns: " << timer.elapsed() << std::endl;
+#endif
+
+#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
+std::cout << "enrich" << std::endl;
+#endif
+ typename Strategy::side_strategy_type side_strategy;
+ geometry::enrich_intersection_points<Reverse1, Reverse2>(turn_points,
+ Direction == overlay_union
+ ? geometry::detail::overlay::operation_union
+ : geometry::detail::overlay::operation_intersection,
+ geometry1, geometry2,
+ side_strategy);
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << "enrich_intersection_points: " << timer.elapsed() << std::endl;
+#endif
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
+std::cout << "traverse" << std::endl;
+#endif
+ // Traverse through intersection/turn points and create rings of them.
+ // Note that these rings are always in clockwise order, even in CCW polygons,
+ // and are marked as "to be reversed" below
+ ring_container_type rings;
+ traverse<Reverse1, Reverse2, Geometry1, Geometry2>::apply
+ (
+ geometry1, geometry2,
+ Direction == overlay_union
+ ? geometry::detail::overlay::operation_union
+ : geometry::detail::overlay::operation_intersection,
+ turn_points, rings
+ );
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << "traverse: " << timer.elapsed() << std::endl;
+#endif
+
+
+ std::map<ring_identifier, int> map;
+ map_turns(map, turn_points);
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << "map_turns: " << timer.elapsed() << std::endl;
+#endif
+
+ typedef ring_properties<typename geometry::point_type<GeometryOut>::type> properties;
+
+ std::map<ring_identifier, properties> selected;
+ select_rings<Direction>(geometry1, geometry2, map, selected, ! turn_points.empty());
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << "select_rings: " << timer.elapsed() << std::endl;
+#endif
+
+
+ // Add rings created during traversal
+ {
+ ring_identifier id(2, 0, -1);
+ for (typename boost::range_iterator<ring_container_type>::type
+ it = boost::begin(rings);
+ it != boost::end(rings);
+ ++it)
+ {
+ selected[id] = properties(*it, true);
+ selected[id].reversed = ReverseOut;
+ id.multi_index++;
+ }
+ }
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << "add traversal rings: " << timer.elapsed() << std::endl;
+#endif
+
+
+ assign_parents(geometry1, geometry2, rings, selected);
+
+#ifdef BOOST_GEOMETRY_TIME_OVERLAY
+ std::cout << "assign_parents: " << timer.elapsed() << std::endl;
+#endif
+
+ return add_rings<GeometryOut>(selected, geometry1, geometry2, rings, out);
+ }
+};
+
+
+// Metafunction helper for intersection and union
+template <order_selector Selector, bool Reverse = false>
+struct do_reverse {};
+
+template <>
+struct do_reverse<clockwise, false> : boost::false_type {};
+
+template <>
+struct do_reverse<clockwise, true> : boost::true_type {};
+
+template <>
+struct do_reverse<counterclockwise, false> : boost::true_type {};
+
+template <>
+struct do_reverse<counterclockwise, true> : boost::false_type {};
+
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/overlay_type.hpp b/src/boost/geometry/algorithms/detail/overlay/overlay_type.hpp
new file mode 100644
index 0000000..af62131
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/overlay_type.hpp
@@ -0,0 +1,29 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
+
+
+
+namespace boost { namespace geometry
+{
+
+enum overlay_type
+{
+ overlay_union,
+ overlay_intersection,
+ overlay_difference,
+ overlay_dissolve
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_TYPE_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/ring_properties.hpp b/src/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
new file mode 100644
index 0000000..a608869
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RING_PROPERTIES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RING_PROPERTIES_HPP
+
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+template <typename Point>
+struct ring_properties
+{
+ typedef Point point_type;
+ typedef typename default_area_result<Point>::type area_type;
+
+ // Filled by "select_rings"
+ Point point;
+ area_type area;
+
+ // Filled by "update_selection_map"
+ int within_code;
+ bool reversed;
+
+ // Filled/used by "assign_rings"
+ bool discarded;
+ ring_identifier parent;
+ area_type parent_area;
+ std::vector<ring_identifier> children;
+
+ inline ring_properties()
+ : area(area_type())
+ , within_code(-1)
+ , reversed(false)
+ , discarded(false)
+ , parent_area(-1)
+ {}
+
+ template <typename RingOrBox>
+ inline ring_properties(RingOrBox const& ring_or_box, bool midpoint)
+ : within_code(-1)
+ , reversed(false)
+ , discarded(false)
+ , parent_area(-1)
+ {
+ this->area = geometry::area(ring_or_box);
+ geometry::point_on_border(this->point, ring_or_box, midpoint);
+ }
+
+ inline area_type get_area() const
+ {
+ return reversed ? -area : area;
+ }
+};
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RING_PROPERTIES_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp b/src/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
new file mode 100644
index 0000000..007113f
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp
@@ -0,0 +1,91 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SEGMENT_IDENTIFIER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SEGMENT_IDENTIFIER_HPP
+
+
+#if defined(BOOST_GEOMETRY_DEBUG_OVERLAY)
+# define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER
+#endif
+
+
+#include <vector>
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+// Internal struct to uniquely identify a segment
+// on a linestring,ring
+// or polygon (needs ring_index)
+// or multi-geometry (needs multi_index)
+struct segment_identifier
+{
+ inline segment_identifier()
+ : source_index(-1)
+ , multi_index(-1)
+ , ring_index(-1)
+ , segment_index(-1)
+ {}
+
+ inline segment_identifier(int src, int mul, int rin, int seg)
+ : source_index(src)
+ , multi_index(mul)
+ , ring_index(rin)
+ , segment_index(seg)
+ {}
+
+ inline bool operator<(segment_identifier const& other) const
+ {
+ return source_index != other.source_index ? source_index < other.source_index
+ : multi_index !=other.multi_index ? multi_index < other.multi_index
+ : ring_index != other.ring_index ? ring_index < other.ring_index
+ : segment_index < other.segment_index
+ ;
+ }
+
+ inline bool operator==(segment_identifier const& other) const
+ {
+ return source_index == other.source_index
+ && segment_index == other.segment_index
+ && ring_index == other.ring_index
+ && multi_index == other.multi_index
+ ;
+ }
+
+#if defined(BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER)
+ friend std::ostream& operator<<(std::ostream &os, segment_identifier const& seg_id)
+ {
+ std::cout
+ << "s:" << seg_id.source_index
+ << ", v:" << seg_id.segment_index // ~vertex
+ ;
+ if (seg_id.ring_index >= 0) std::cout << ", r:" << seg_id.ring_index;
+ if (seg_id.multi_index >= 0) std::cout << ", m:" << seg_id.multi_index;
+ return os;
+ }
+#endif
+
+ int source_index;
+ int multi_index;
+ int ring_index;
+ int segment_index;
+};
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SEGMENT_IDENTIFIER_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/select_rings.hpp b/src/boost/geometry/algorithms/detail/overlay/select_rings.hpp
new file mode 100644
index 0000000..f664b19
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/select_rings.hpp
@@ -0,0 +1,295 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
+
+#include <map>
+
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+#include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+namespace dispatch
+{
+
+ template <typename Tag, typename Geometry>
+ struct select_rings
+ {};
+
+ template <typename Box>
+ struct select_rings<box_tag, Box>
+ {
+ template <typename Geometry, typename Map>
+ static inline void apply(Box const& box, Geometry const& ,
+ ring_identifier const& id, Map& map, bool midpoint)
+ {
+ map[id] = typename Map::mapped_type(box, midpoint);
+ }
+
+ template <typename Map>
+ static inline void apply(Box const& box,
+ ring_identifier const& id, Map& map, bool midpoint)
+ {
+ map[id] = typename Map::mapped_type(box, midpoint);
+ }
+ };
+
+ template <typename Ring>
+ struct select_rings<ring_tag, Ring>
+ {
+ template <typename Geometry, typename Map>
+ static inline void apply(Ring const& ring, Geometry const& ,
+ ring_identifier const& id, Map& map, bool midpoint)
+ {
+ if (boost::size(ring) > 0)
+ {
+ map[id] = typename Map::mapped_type(ring, midpoint);
+ }
+ }
+
+ template <typename Map>
+ static inline void apply(Ring const& ring,
+ ring_identifier const& id, Map& map, bool midpoint)
+ {
+ if (boost::size(ring) > 0)
+ {
+ map[id] = typename Map::mapped_type(ring, midpoint);
+ }
+ }
+ };
+
+
+ template <typename Polygon>
+ struct select_rings<polygon_tag, Polygon>
+ {
+ template <typename Geometry, typename Map>
+ static inline void apply(Polygon const& polygon, Geometry const& geometry,
+ ring_identifier id, Map& map, bool midpoint)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+ typedef select_rings<ring_tag, ring_type> per_ring;
+
+ per_ring::apply(exterior_ring(polygon), geometry, id, map, midpoint);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ id.ring_index++;
+ per_ring::apply(*it, geometry, id, map, midpoint);
+ }
+ }
+
+ template <typename Map>
+ static inline void apply(Polygon const& polygon,
+ ring_identifier id, Map& map, bool midpoint)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+ typedef select_rings<ring_tag, ring_type> per_ring;
+
+ per_ring::apply(exterior_ring(polygon), id, map, midpoint);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ id.ring_index++;
+ per_ring::apply(*it, id, map, midpoint);
+ }
+ }
+ };
+}
+
+
+template<overlay_type OverlayType>
+struct decide
+{};
+
+template<>
+struct decide<overlay_union>
+{
+ template <typename Code>
+ static bool include(ring_identifier const& , Code const& code)
+ {
+ return code.within_code * -1 == 1;
+ }
+
+ template <typename Code>
+ static bool reversed(ring_identifier const& , Code const& )
+ {
+ return false;
+ }
+};
+
+template<>
+struct decide<overlay_difference>
+{
+ template <typename Code>
+ static bool include(ring_identifier const& id, Code const& code)
+ {
+ bool is_first = id.source_index == 0;
+ return code.within_code * -1 * (is_first ? 1 : -1) == 1;
+ }
+
+ template <typename Code>
+ static bool reversed(ring_identifier const& id, Code const& code)
+ {
+ return include(id, code) && id.source_index == 1;
+ }
+};
+
+template<>
+struct decide<overlay_intersection>
+{
+ template <typename Code>
+ static bool include(ring_identifier const& , Code const& code)
+ {
+ return code.within_code * 1 == 1;
+ }
+
+ template <typename Code>
+ static bool reversed(ring_identifier const& , Code const& )
+ {
+ return false;
+ }
+};
+
+
+template
+<
+ overlay_type OverlayType,
+ typename Geometry1, typename Geometry2,
+ typename IntersectionMap, typename SelectionMap
+>
+inline void update_selection_map(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ IntersectionMap const& intersection_map,
+ SelectionMap const& map_with_all, SelectionMap& selection_map)
+{
+ selection_map.clear();
+
+ for (typename SelectionMap::const_iterator it = boost::begin(map_with_all);
+ it != boost::end(map_with_all);
+ ++it)
+ {
+ /*
+ int union_code = it->second.within_code * -1;
+ bool is_first = it->first.source_index == 0;
+ std::cout << it->first << " " << it->second.area
+ << ": " << it->second.within_code
+ << " union: " << union_code
+ << " intersection: " << (it->second.within_code * 1)
+ << " G1-G2: " << (union_code * (is_first ? 1 : -1))
+ << " G2-G1: " << (union_code * (is_first ? -1 : 1))
+ << " -> " << (decide<OverlayType>::include(it->first, it->second) ? "INC" : "")
+ << decide<OverlayType>::reverse(it->first, it->second)
+ << std::endl;
+ */
+
+ bool found = intersection_map.find(it->first) != intersection_map.end();
+ if (! found)
+ {
+ ring_identifier const id = it->first;
+ typename SelectionMap::mapped_type properties = it->second; // Copy by value
+
+ // Calculate the "within code" (previously this was done earlier but is
+ // must efficienter here - it can be even more efficient doing it all at once,
+ // using partition, TODO)
+ // So though this is less elegant than before, it avoids many unused point-in-poly calculations
+ switch(id.source_index)
+ {
+ case 0 :
+ properties.within_code
+ = geometry::within(properties.point, geometry2) ? 1 : -1;
+ break;
+ case 1 :
+ properties.within_code
+ = geometry::within(properties.point, geometry1) ? 1 : -1;
+ break;
+ }
+
+ if (decide<OverlayType>::include(id, properties))
+ {
+ properties.reversed = decide<OverlayType>::reversed(id, properties);
+ selection_map[id] = properties;
+ }
+ }
+ }
+}
+
+
+/*!
+\brief The function select_rings select rings based on the overlay-type (union,intersection)
+*/
+template
+<
+ overlay_type OverlayType,
+ typename Geometry1, typename Geometry2,
+ typename IntersectionMap, typename SelectionMap
+>
+inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ IntersectionMap const& intersection_map,
+ SelectionMap& selection_map, bool midpoint)
+{
+ typedef typename geometry::tag<Geometry1>::type tag1;
+ typedef typename geometry::tag<Geometry2>::type tag2;
+
+ SelectionMap map_with_all;
+ dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2,
+ ring_identifier(0, -1, -1), map_with_all, midpoint);
+ dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1,
+ ring_identifier(1, -1, -1), map_with_all, midpoint);
+
+ update_selection_map<OverlayType>(geometry1, geometry2, intersection_map,
+ map_with_all, selection_map);
+}
+
+template
+<
+ overlay_type OverlayType,
+ typename Geometry,
+ typename IntersectionMap, typename SelectionMap
+>
+inline void select_rings(Geometry const& geometry,
+ IntersectionMap const& intersection_map,
+ SelectionMap& selection_map, bool midpoint)
+{
+ typedef typename geometry::tag<Geometry>::type tag;
+
+ SelectionMap map_with_all;
+ dispatch::select_rings<tag, Geometry>::apply(geometry,
+ ring_identifier(0, -1, -1), map_with_all, midpoint);
+
+ update_selection_map<OverlayType>(geometry, geometry, intersection_map,
+ map_with_all, selection_map);
+}
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/src/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
new file mode 100644
index 0000000..9c4c993
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp
@@ -0,0 +1,308 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/partition.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace self_get_turn_points
+{
+
+struct no_interrupt_policy
+{
+ static bool const enabled = false;
+ static bool const has_intersections = false;
+
+
+ template <typename Range>
+ static inline bool apply(Range const&)
+ {
+ return false;
+ }
+};
+
+
+
+
+class self_ip_exception : public geometry::exception {};
+
+template
+<
+ typename Geometry,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct self_section_visitor
+{
+ Geometry const& m_geometry;
+ Turns& m_turns;
+ InterruptPolicy& m_interrupt_policy;
+
+ inline self_section_visitor(Geometry const& g,
+ Turns& turns, InterruptPolicy& ip)
+ : m_geometry(g)
+ , m_turns(turns)
+ , m_interrupt_policy(ip)
+ {}
+
+ template <typename Section>
+ inline bool apply(Section const& sec1, Section const& sec2)
+ {
+ if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box)
+ && ! sec1.duplicate
+ && ! sec2.duplicate)
+ {
+ detail::get_turns::get_turns_in_sections
+ <
+ Geometry, Geometry,
+ false, false,
+ Section, Section,
+ Turns, TurnPolicy,
+ InterruptPolicy
+ >::apply(
+ 0, m_geometry, sec1,
+ 0, m_geometry, sec2,
+ false,
+ m_turns, m_interrupt_policy);
+ }
+ if (m_interrupt_policy.has_intersections)
+ {
+ // TODO: we should give partition an interrupt policy.
+ // Now we throw, and catch below, to stop the partition loop.
+ throw self_ip_exception();
+ }
+ return true;
+ }
+
+};
+
+
+
+template
+<
+ typename Geometry,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns
+{
+ static inline bool apply(
+ Geometry const& geometry,
+ Turns& turns,
+ InterruptPolicy& interrupt_policy)
+ {
+ typedef model::box
+ <
+ typename geometry::point_type<Geometry>::type
+ > box_type;
+ typedef typename geometry::sections
+ <
+ box_type, 1
+ > sections_type;
+
+ sections_type sec;
+ geometry::sectionalize<false>(geometry, sec);
+
+ self_section_visitor
+ <
+ Geometry,
+ Turns, TurnPolicy, InterruptPolicy
+ > visitor(geometry, turns, interrupt_policy);
+
+ try
+ {
+ geometry::partition
+ <
+ box_type,
+ detail::get_turns::get_section_box,
+ detail::get_turns::ovelaps_section_box
+ >::apply(sec, visitor);
+ }
+ catch(self_ip_exception const& )
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+
+}} // namespace detail::self_get_turn_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryTag,
+ typename Geometry,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct self_get_turn_points
+{
+};
+
+
+template
+<
+ typename Ring,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct self_get_turn_points
+ <
+ ring_tag, Ring,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >
+ : detail::self_get_turn_points::get_turns
+ <
+ Ring,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >
+{};
+
+
+template
+<
+ typename Box,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct self_get_turn_points
+ <
+ box_tag, Box,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >
+{
+ static inline bool apply(
+ Box const& ,
+ Turns& ,
+ InterruptPolicy& )
+ {
+ return true;
+ }
+};
+
+
+template
+<
+ typename Polygon,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct self_get_turn_points
+ <
+ polygon_tag, Polygon,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >
+ : detail::self_get_turn_points::get_turns
+ <
+ Polygon,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Calculate self intersections of a geometry
+ \ingroup overlay
+ \tparam Geometry geometry type
+ \tparam Turns type of intersection container
+ (e.g. vector of "intersection/turn point"'s)
+ \param geometry geometry
+ \param turns container which will contain intersection points
+ \param interrupt_policy policy determining if process is stopped
+ when intersection is found
+ */
+template
+<
+ typename AssignPolicy,
+ typename Geometry,
+ typename Turns,
+ typename InterruptPolicy
+>
+inline void self_turns(Geometry const& geometry,
+ Turns& turns, InterruptPolicy& interrupt_policy)
+{
+ concept::check<Geometry const>();
+
+ typedef typename strategy_intersection
+ <
+ typename cs_tag<Geometry>::type,
+ Geometry,
+ Geometry,
+ typename boost::range_value<Turns>::type
+ >::segment_intersection_strategy_type strategy_type;
+
+ typedef detail::overlay::get_turn_info
+ <
+ typename point_type<Geometry>::type,
+ typename point_type<Geometry>::type,
+ typename boost::range_value<Turns>::type,
+ detail::overlay::assign_null_policy
+ > TurnPolicy;
+
+ dispatch::self_get_turn_points
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >::apply(geometry, turns, interrupt_policy);
+}
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/stream_info.hpp b/src/boost/geometry/algorithms/detail/overlay/stream_info.hpp
new file mode 100644
index 0000000..eebe381
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/stream_info.hpp
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_STREAM_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_STREAM_INFO_HPP
+
+
+#include <string>
+
+#include <boost/array.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+ static inline std::string dir(int d)
+ {
+ return d == 0 ? "-" : (d == 1 ? "L" : d == -1 ? "R" : "#");
+ }
+ static inline std::string how_str(int h)
+ {
+ return h == 0 ? "-" : (h == 1 ? "A" : "D");
+ }
+
+ template <typename P>
+ std::ostream& operator<<(std::ostream &os, turn_info<P> const& info)
+ {
+ typename geometry::coordinate_type<P>::type d = info.distance;
+ os << "\t"
+ << " src " << info.seg_id.source_index
+ << " seg " << info.seg_id.segment_index
+ << " (// " << info.other_id.source_index
+ << "." << info.other_id.segment_index << ")"
+ << " how " << info.how
+ << "[" << how_str(info.arrival)
+ << " " << dir(info.direction)
+ << (info.opposite ? " o" : "")
+ << "]"
+ << " sd "
+ << dir(info.sides.get<0,0>())
+ << dir(info.sides.get<0,1>())
+ << dir(info.sides.get<1,0>())
+ << dir(info.sides.get<1,1>())
+ << " nxt seg " << info.travels_to_vertex_index
+ << " , ip " << info.travels_to_ip_index
+ << " , or " << info.next_ip_index
+ << " dst " << double(d)
+ << info.visit_state;
+ if (info.flagged)
+ {
+ os << " FLAGGED";
+ }
+ return os;
+ }
+
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_STREAM_INFO_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/traversal_info.hpp b/src/boost/geometry/algorithms/detail/overlay/traversal_info.hpp
new file mode 100644
index 0000000..810a27a
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/traversal_info.hpp
@@ -0,0 +1,47 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_INFO_HPP
+
+
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/visit_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+template <typename P>
+struct traversal_turn_operation : public turn_operation
+{
+ enrichment_info<P> enriched;
+ visit_info visited;
+};
+
+template <typename P>
+struct traversal_turn_info : public turn_info<P, traversal_turn_operation<P> >
+{};
+
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_INFO_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/traverse.hpp b/src/boost/geometry/algorithms/detail/overlay/traverse.hpp
new file mode 100644
index 0000000..12daafa
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/traverse.hpp
@@ -0,0 +1,395 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSE_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
+#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
+#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \
+ || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \
+ || defined(BOOST_GEOMETRY_DEBUG_TRAVERSE)
+# include <string>
+# include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
+# include <boost/geometry/io/wkt/wkt.hpp>
+#endif
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+template <typename Turn, typename Operation>
+#ifdef BOOST_GEOMETRY_DEBUG_TRAVERSE
+inline void debug_traverse(Turn const& turn, Operation op,
+ std::string const& header)
+{
+ std::cout << header
+ << " at " << op.seg_id
+ << " meth: " << method_char(turn.method)
+ << " op: " << operation_char(op.operation)
+ << " vis: " << visited_char(op.visited)
+ << " of: " << operation_char(turn.operations[0].operation)
+ << operation_char(turn.operations[1].operation)
+ << " " << geometry::wkt(turn.point)
+ << std::endl;
+
+ if (boost::contains(header, "Finished"))
+ {
+ std::cout << std::endl;
+ }
+}
+#else
+inline void debug_traverse(Turn const& , Operation, std::string const& )
+{
+}
+#endif
+
+
+template <typename Info, typename Turn>
+inline void set_visited_for_continue(Info& info, Turn const& turn)
+{
+ // On "continue", set "visited" for ALL directions
+ if (turn.operation == detail::overlay::operation_continue)
+ {
+ for (typename boost::range_iterator
+ <
+ typename Info::container_type
+ >::type it = boost::begin(info.operations);
+ it != boost::end(info.operations);
+ ++it)
+ {
+ if (it->visited.none())
+ {
+ it->visited.set_visited();
+ }
+ }
+ }
+}
+
+
+template
+<
+ bool Reverse1, bool Reverse2,
+ typename GeometryOut,
+ typename G1,
+ typename G2,
+ typename Turns,
+ typename IntersectionInfo
+>
+inline bool assign_next_ip(G1 const& g1, G2 const& g2,
+ Turns& turns,
+ typename boost::range_iterator<Turns>::type& ip,
+ GeometryOut& current_output,
+ IntersectionInfo& info,
+ segment_identifier& seg_id)
+{
+ info.visited.set_visited();
+ set_visited_for_continue(*ip, info);
+
+ // If there is no next IP on this segment
+ if (info.enriched.next_ip_index < 0)
+ {
+ if (info.enriched.travels_to_vertex_index < 0
+ || info.enriched.travels_to_ip_index < 0)
+ {
+ return false;
+ }
+
+ BOOST_ASSERT(info.enriched.travels_to_vertex_index >= 0);
+ BOOST_ASSERT(info.enriched.travels_to_ip_index >= 0);
+
+ if (info.seg_id.source_index == 0)
+ {
+ geometry::copy_segments<Reverse1>(g1, info.seg_id,
+ info.enriched.travels_to_vertex_index,
+ current_output);
+ }
+ else
+ {
+ geometry::copy_segments<Reverse2>(g2, info.seg_id,
+ info.enriched.travels_to_vertex_index,
+ current_output);
+ }
+ seg_id = info.seg_id;
+ ip = boost::begin(turns) + info.enriched.travels_to_ip_index;
+ }
+ else
+ {
+ ip = boost::begin(turns) + info.enriched.next_ip_index;
+ seg_id = info.seg_id;
+ }
+
+ detail::overlay::append_no_duplicates(current_output, ip->point);
+ return true;
+}
+
+
+inline bool select_source(operation_type operation, int source1, int source2)
+{
+ return (operation == operation_intersection && source1 != source2)
+ || (operation == operation_union && source1 == source2)
+ ;
+}
+
+
+template
+<
+ typename Turn,
+ typename Iterator
+>
+inline bool select_next_ip(operation_type operation,
+ Turn& turn,
+ segment_identifier const& seg_id,
+ Iterator& selected)
+{
+ if (turn.discarded)
+ {
+ return false;
+ }
+ bool has_tp = false;
+ selected = boost::end(turn.operations);
+ for (Iterator it = boost::begin(turn.operations);
+ it != boost::end(turn.operations);
+ ++it)
+ {
+ if (it->visited.started())
+ {
+ selected = it;
+ //std::cout << " RETURN";
+ return true;
+ }
+
+ // In some cases there are two alternatives.
+ // For "ii", take the other one (alternate)
+ // UNLESS the other one is already visited
+ // For "uu", take the same one (see above);
+ // For "cc", take either one, but if there is a starting one,
+ // take that one.
+ if ( (it->operation == operation_continue
+ && (! has_tp || it->visited.started()
+ )
+ )
+ || (it->operation == operation
+ && ! it->visited.finished()
+ && (! has_tp
+ || select_source(operation,
+ it->seg_id.source_index, seg_id.source_index)
+ )
+ )
+ )
+ {
+ selected = it;
+ debug_traverse(turn, *it, " Candidate");
+ has_tp = true;
+ }
+ }
+
+ if (has_tp)
+ {
+ debug_traverse(turn, *selected, " Accepted");
+ }
+
+
+ return has_tp;
+}
+
+
+
+/*!
+ \brief Traverses through intersection points / geometries
+ \ingroup overlay
+ */
+template
+<
+ bool Reverse1, bool Reverse2,
+ typename Geometry1,
+ typename Geometry2,
+ typename Backtrack = backtrack_check_self_intersections<Geometry1, Geometry2>
+>
+class traverse
+{
+public :
+ template <typename Turns, typename Rings>
+ static inline void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ detail::overlay::operation_type operation,
+ Turns& turns, Rings& rings)
+ {
+ typedef typename boost::range_iterator<Turns>::type turn_iterator;
+ typedef typename boost::range_value<Turns>::type turn_type;
+ typedef typename boost::range_iterator
+ <
+ typename turn_type::container_type
+ >::type turn_operation_iterator_type;
+
+ std::size_t size_at_start = boost::size(rings);
+
+ typename Backtrack::state_type state;
+ do
+ {
+ state.reset();
+
+ // Iterate through all unvisited points
+ for (turn_iterator it = boost::begin(turns);
+ state.good() && it != boost::end(turns);
+ ++it)
+ {
+ // Skip discarded ones
+ if (! (it->is_discarded() || it->blocked()))
+ {
+ for (turn_operation_iterator_type iit = boost::begin(it->operations);
+ state.good() && iit != boost::end(it->operations);
+ ++iit)
+ {
+ if (iit->visited.none()
+ && ! iit->visited.rejected()
+ && (iit->operation == operation
+ || iit->operation == detail::overlay::operation_continue)
+ )
+ {
+ set_visited_for_continue(*it, *iit);
+
+ typename boost::range_value<Rings>::type current_output;
+ detail::overlay::append_no_duplicates(current_output,
+ it->point, true);
+
+ turn_iterator current = it;
+ turn_operation_iterator_type current_iit = iit;
+ segment_identifier current_seg_id;
+
+ if (! detail::overlay::assign_next_ip<Reverse1, Reverse2>(
+ geometry1, geometry2,
+ turns,
+ current, current_output,
+ *iit, current_seg_id))
+ {
+ Backtrack::apply(
+ size_at_start,
+ rings, current_output, turns, *current_iit,
+ "No next IP",
+ geometry1, geometry2, state);
+ }
+
+ if (! detail::overlay::select_next_ip(
+ operation,
+ *current,
+ current_seg_id,
+ current_iit))
+ {
+ Backtrack::apply(
+ size_at_start,
+ rings, current_output, turns, *iit,
+ "Dead end at start",
+ geometry1, geometry2, state);
+ }
+ else
+ {
+
+ iit->visited.set_started();
+ detail::overlay::debug_traverse(*it, *iit, "-> Started");
+ detail::overlay::debug_traverse(*current, *current_iit, "Selected ");
+
+
+ unsigned int i = 0;
+
+ while (current_iit != iit && state.good())
+ {
+ if (current_iit->visited.visited())
+ {
+ // It visits a visited node again, without passing the start node.
+ // This makes it suspicious for endless loops
+ Backtrack::apply(
+ size_at_start,
+ rings, current_output, turns, *iit,
+ "Visit again",
+ geometry1, geometry2, state);
+ }
+ else
+ {
+
+
+ // We assume clockwise polygons only, non self-intersecting, closed.
+ // However, the input might be different, and checking validity
+ // is up to the library user.
+
+ // Therefore we make here some sanity checks. If the input
+ // violates the assumptions, the output polygon will not be correct
+ // but the routine will stop and output the current polygon, and
+ // will continue with the next one.
+
+ // Below three reasons to stop.
+ detail::overlay::assign_next_ip<Reverse1, Reverse2>(
+ geometry1, geometry2,
+ turns, current, current_output,
+ *current_iit, current_seg_id);
+
+ if (! detail::overlay::select_next_ip(
+ operation,
+ *current,
+ current_seg_id,
+ current_iit))
+ {
+ // Should not occur in valid (non-self-intersecting) polygons
+ // Should not occur in self-intersecting polygons without spikes
+ // Might occur in polygons with spikes
+ Backtrack::apply(
+ size_at_start,
+ rings, current_output, turns, *iit,
+ "Dead end",
+ geometry1, geometry2, state);
+ }
+ detail::overlay::debug_traverse(*current, *current_iit, "Selected ");
+
+ if (i++ > 2 + 2 * turns.size())
+ {
+ // Sanity check: there may be never more loops
+ // than turn points.
+ // Turn points marked as "ii" can be visited twice.
+ Backtrack::apply(
+ size_at_start,
+ rings, current_output, turns, *iit,
+ "Endless loop",
+ geometry1, geometry2, state);
+ }
+ }
+ }
+
+ if (state.good())
+ {
+ iit->visited.set_finished();
+ detail::overlay::debug_traverse(*current, *iit, "->Finished");
+ rings.push_back(current_output);
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (! state.good());
+ }
+};
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSE_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/turn_info.hpp b/src/boost/geometry/algorithms/detail/overlay/turn_info.hpp
new file mode 100644
index 0000000..89a60b2
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/turn_info.hpp
@@ -0,0 +1,152 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TURN_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TURN_INFO_HPP
+
+
+#include <boost/array.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+enum operation_type
+{
+ operation_none,
+ operation_union,
+ operation_intersection,
+ operation_blocked,
+ operation_continue,
+ operation_opposite
+};
+
+
+enum method_type
+{
+ method_none,
+ method_disjoint,
+ method_crosses,
+ method_touch,
+ method_touch_interior,
+ method_collinear,
+ method_equal,
+ method_error
+};
+
+
+/*!
+ \brief Turn operation: operation
+ \details Information necessary for traversal phase (a phase
+ of the overlay process). The information is gathered during the
+ get_turns (segment intersection) phase.
+ The class is to be included in the turn_info class, either direct
+ or a derived or similar class with more (e.g. enrichment) information.
+ */
+struct turn_operation
+{
+ operation_type operation;
+ segment_identifier seg_id;
+ segment_identifier other_id;
+
+ inline turn_operation()
+ : operation(operation_none)
+ {}
+};
+
+
+/*!
+ \brief Turn information: intersection point, method, and turn information
+ \details Information necessary for traversal phase (a phase
+ of the overlay process). The information is gathered during the
+ get_turns (segment intersection) phase.
+ \tparam Point point type of intersection point
+ \tparam Operation gives classes opportunity to add additional info
+ \tparam Container gives classes opportunity to define how operations are stored
+ */
+template
+<
+ typename Point,
+ typename Operation = turn_operation,
+ typename Container = boost::array<Operation, 2>
+>
+struct turn_info
+{
+ typedef Point point_type;
+ typedef Operation turn_operation_type;
+ typedef Container container_type;
+
+ Point point;
+ method_type method;
+ bool discarded;
+
+
+ Container operations;
+
+ inline turn_info()
+ : method(method_none)
+ , discarded(false)
+ {}
+
+ inline bool both(operation_type type) const
+ {
+ return has12(type, type);
+ }
+
+ inline bool has(operation_type type) const
+ {
+ return this->operations[0].operation == type
+ || this->operations[1].operation == type;
+ }
+
+ inline bool combination(operation_type type1, operation_type type2) const
+ {
+ return has12(type1, type2) || has12(type2, type1);
+ }
+
+
+ inline bool is_discarded() const { return discarded; }
+ inline bool blocked() const
+ {
+ return both(operation_blocked);
+ }
+ inline bool opposite() const
+ {
+ return both(operation_opposite);
+ }
+ inline bool any_blocked() const
+ {
+ return has(operation_blocked);
+ }
+
+
+private :
+ inline bool has12(operation_type type1, operation_type type2) const
+ {
+ return this->operations[0].operation == type1
+ && this->operations[1].operation == type2
+ ;
+ }
+
+};
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TURN_INFO_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/visit_info.hpp b/src/boost/geometry/algorithms/detail/overlay/visit_info.hpp
new file mode 100644
index 0000000..6be63f4
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/visit_info.hpp
@@ -0,0 +1,136 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_VISIT_INFO_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_VISIT_INFO_HPP
+
+
+#ifdef BOOST_GEOMETRY_USE_MSM
+# include <boost/geometry/algorithms/detail/overlay/msm_state.hpp>
+#endif
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+#if ! defined(BOOST_GEOMETRY_USE_MSM)
+
+class visit_info
+{
+private :
+ static const int NONE = 0;
+ static const int STARTED = 1;
+ static const int VISITED = 2;
+ static const int FINISHED = 3;
+ static const int REJECTED = 4;
+
+ int m_visit_code;
+ bool m_rejected;
+
+public:
+ inline visit_info()
+ : m_visit_code(0)
+ , m_rejected(false)
+ {}
+
+ inline void set_visited() { m_visit_code = VISITED; }
+ inline void set_started() { m_visit_code = STARTED; }
+ inline void set_finished() { m_visit_code = FINISHED; }
+ inline void set_rejected()
+ {
+ m_visit_code = REJECTED;
+ m_rejected = true;
+ }
+
+ inline bool none() const { return m_visit_code == NONE; }
+ inline bool visited() const { return m_visit_code == VISITED; }
+ inline bool started() const { return m_visit_code == STARTED; }
+ inline bool finished() const { return m_visit_code == FINISHED; }
+ inline bool rejected() const { return m_rejected; }
+
+ inline void clear()
+ {
+ if (! rejected())
+ {
+ m_visit_code = NONE;
+ }
+ }
+
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
+ friend std::ostream& operator<<(std::ostream &os, visit_info const& v)
+ {
+ if (v.m_visit_code != 0)
+ {
+ os << " VIS: " << int(v.m_visit_code);
+ }
+ return os;
+ }
+#endif
+
+};
+
+
+#else
+
+
+class visit_info
+{
+
+private :
+
+#ifndef USE_MSM_MINI
+ mutable
+#endif
+ traverse_state state;
+
+public :
+ inline visit_info()
+ {
+ state.start();
+ }
+
+ inline void set_none() { state.process_event(none()); } // Not Yet Implemented!
+ inline void set_visited() { state.process_event(visit()); }
+ inline void set_started() { state.process_event(starting()); }
+ inline void set_finished() { state.process_event(finish()); }
+
+#ifdef USE_MSM_MINI
+ inline bool none() const { return state.flag_none(); }
+ inline bool visited() const { return state.flag_visited(); }
+ inline bool started() const { return state.flag_started(); }
+#else
+ inline bool none() const { return state.is_flag_active<is_init>(); }
+ inline bool visited() const { return state.is_flag_active<is_visited>(); }
+ inline bool started() const { return state.is_flag_active<is_started>(); }
+#endif
+
+#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
+ friend std::ostream& operator<<(std::ostream &os, visit_info const& v)
+ {
+ return os;
+ }
+#endif
+};
+#endif
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_VISIT_INFO_HPP
diff --git a/src/boost/geometry/algorithms/detail/overlay/within_util.hpp b/src/boost/geometry/algorithms/detail/overlay/within_util.hpp
new file mode 100644
index 0000000..8618b81
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/overlay/within_util.hpp
@@ -0,0 +1,98 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_WITHIN_UTIL_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_WITHIN_UTIL_HPP
+
+
+
+#include <boost/geometry/algorithms/within.hpp>
+#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+
+template<typename Tag, typename Point, typename Geometry>
+struct within_code
+{};
+
+template<typename Point, typename Box>
+struct within_code<box_tag, Point, Box>
+{
+ static inline int apply(Point const& point, Box const& box)
+ {
+ // 1. Check outside
+ if (get<0>(point) < get<min_corner, 0>(box)
+ || get<0>(point) > get<max_corner, 0>(box)
+ || get<1>(point) < get<min_corner, 1>(box)
+ || get<1>(point) > get<max_corner, 1>(box))
+ {
+ return -1;
+ }
+ // 2. Check border
+ if (geometry::math::equals(get<0>(point), get<min_corner, 0>(box))
+ || geometry::math::equals(get<0>(point), get<max_corner, 0>(box))
+ || geometry::math::equals(get<1>(point), get<min_corner, 1>(box))
+ || geometry::math::equals(get<1>(point), get<max_corner, 1>(box)))
+ {
+ return 0;
+ }
+ return 1;
+ }
+};
+template<typename Point, typename Ring>
+struct within_code<ring_tag, Point, Ring>
+{
+ static inline int apply(Point const& point, Ring const& ring)
+ {
+ // Same as point_in_ring but here ALWAYS with winding.
+ typedef strategy::within::winding<Point> strategy_type;
+
+ return detail::within::point_in_ring
+ <
+ Point,
+ Ring,
+ order_as_direction<geometry::point_order<Ring>::value>::value,
+ geometry::closure<Ring>::value,
+ strategy_type
+ >::apply(point, ring, strategy_type());
+ }
+};
+
+
+template<typename Point, typename Geometry>
+inline int point_in_ring(Point const& point, Geometry const& geometry)
+{
+ return within_code<typename geometry::tag<Geometry>::type, Point, Geometry>
+ ::apply(point, geometry);
+}
+
+template<typename Point, typename Geometry>
+inline bool within_or_touch(Point const& point, Geometry const& geometry)
+{
+ return within_code<typename geometry::tag<Geometry>::type, Point, Geometry>
+ ::apply(point, geometry) >= 0;
+}
+
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_WITHIN_UTIL_HPP
diff --git a/src/boost/geometry/algorithms/detail/partition.hpp b/src/boost/geometry/algorithms/detail/partition.hpp
new file mode 100644
index 0000000..45ff52c
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/partition.hpp
@@ -0,0 +1,425 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
+
+#include <vector>
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace partition
+{
+
+typedef std::vector<std::size_t> index_vector_type;
+
+template <int Dimension, typename Box>
+inline void divide_box(Box const& box, Box& lower_box, Box& upper_box)
+{
+ typedef typename coordinate_type<Box>::type ctype;
+
+ // Divide input box into two parts, e.g. left/right
+ ctype two = 2;
+ ctype mid = (geometry::get<min_corner, Dimension>(box)
+ + geometry::get<max_corner, Dimension>(box)) / two;
+
+ lower_box = box;
+ upper_box = box;
+ geometry::set<max_corner, Dimension>(lower_box, mid);
+ geometry::set<min_corner, Dimension>(upper_box, mid);
+}
+
+// Divide collection into three subsets: lower, upper and oversized
+// (not-fitting)
+// (lower == left or bottom, upper == right or top)
+template <typename OverlapsPolicy, typename InputCollection, typename Box>
+static inline void divide_into_subsets(Box const& lower_box,
+ Box const& upper_box,
+ InputCollection const& collection,
+ index_vector_type const& input,
+ index_vector_type& lower,
+ index_vector_type& upper,
+ index_vector_type& exceeding)
+{
+ typedef boost::range_iterator
+ <
+ index_vector_type const
+ >::type index_iterator_type;
+
+ for(index_iterator_type it = boost::begin(input);
+ it != boost::end(input);
+ ++it)
+ {
+ bool const lower_overlapping = OverlapsPolicy::apply(lower_box,
+ collection[*it]);
+ bool const upper_overlapping = OverlapsPolicy::apply(upper_box,
+ collection[*it]);
+
+ if (lower_overlapping && upper_overlapping)
+ {
+ exceeding.push_back(*it);
+ }
+ else if (lower_overlapping)
+ {
+ lower.push_back(*it);
+ }
+ else if (upper_overlapping)
+ {
+ upper.push_back(*it);
+ }
+ else
+ {
+ // Is nowhere! Should not occur!
+ BOOST_ASSERT(true);
+ }
+ }
+}
+
+// Match collection with itself
+template <typename InputCollection, typename Policy>
+static inline void handle_one(InputCollection const& collection,
+ index_vector_type const& input,
+ Policy& policy)
+{
+ typedef boost::range_iterator<index_vector_type const>::type
+ index_iterator_type;
+ // Quadratic behaviour at lowest level (lowest quad, or all exceeding)
+ for(index_iterator_type it1 = boost::begin(input);
+ it1 != boost::end(input);
+ ++it1)
+ {
+ index_iterator_type it2 = it1;
+ for(++it2; it2 != boost::end(input); ++it2)
+ {
+ policy.apply(collection[*it1], collection[*it2]);
+ }
+ }
+}
+
+// Match collection 1 with collection 2
+template <typename InputCollection, typename Policy>
+static inline void handle_two(
+ InputCollection const& collection1, index_vector_type const& input1,
+ InputCollection const& collection2, index_vector_type const& input2,
+ Policy& policy)
+{
+ typedef boost::range_iterator
+ <
+ index_vector_type const
+ >::type index_iterator_type;
+
+ for(index_iterator_type it1 = boost::begin(input1);
+ it1 != boost::end(input1);
+ ++it1)
+ {
+ for(index_iterator_type it2 = boost::begin(input2);
+ it2 != boost::end(input2);
+ ++it2)
+ {
+ policy.apply(collection1[*it1], collection2[*it2]);
+ }
+ }
+}
+
+template
+<
+ int Dimension,
+ typename Box,
+ typename OverlapsPolicy,
+ typename VisitBoxPolicy
+>
+class partition_one_collection
+{
+ typedef std::vector<std::size_t> index_vector_type;
+ typedef typename coordinate_type<Box>::type ctype;
+ typedef partition_one_collection
+ <
+ 1 - Dimension,
+ Box,
+ OverlapsPolicy,
+ VisitBoxPolicy
+ > sub_divide;
+
+ template <typename InputCollection, typename Policy>
+ static inline void next_level(Box const& box,
+ InputCollection const& collection,
+ index_vector_type const& input,
+ int level, std::size_t min_elements,
+ Policy& policy, VisitBoxPolicy& box_policy)
+ {
+ if (boost::size(input) > 0)
+ {
+ if (std::size_t(boost::size(input)) > min_elements && level < 100)
+ {
+ sub_divide::apply(box, collection, input, level + 1,
+ min_elements, policy, box_policy);
+ }
+ else
+ {
+ handle_one(collection, input, policy);
+ }
+ }
+ }
+
+public :
+ template <typename InputCollection, typename Policy>
+ static inline void apply(Box const& box,
+ InputCollection const& collection,
+ index_vector_type const& input,
+ int level,
+ std::size_t min_elements,
+ Policy& policy, VisitBoxPolicy& box_policy)
+ {
+ box_policy.apply(box, level);
+
+ Box lower_box, upper_box;
+ divide_box<Dimension>(box, lower_box, upper_box);
+
+ index_vector_type lower, upper, exceeding;
+ divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection,
+ input, lower, upper, exceeding);
+
+ if (boost::size(exceeding) > 0)
+ {
+ // All what is not fitting a partition should be combined
+ // with each other, and with all which is fitting.
+ handle_one(collection, exceeding, policy);
+ handle_two(collection, exceeding, collection, lower, policy);
+ handle_two(collection, exceeding, collection, upper, policy);
+ }
+
+ // Recursively call operation both parts
+ next_level(lower_box, collection, lower, level, min_elements,
+ policy, box_policy);
+ next_level(upper_box, collection, upper, level, min_elements,
+ policy, box_policy);
+ }
+};
+
+template
+<
+ int Dimension,
+ typename Box,
+ typename OverlapsPolicy,
+ typename VisitBoxPolicy
+>
+class partition_two_collections
+{
+ typedef std::vector<std::size_t> index_vector_type;
+ typedef typename coordinate_type<Box>::type ctype;
+ typedef partition_two_collections
+ <
+ 1 - Dimension,
+ Box,
+ OverlapsPolicy,
+ VisitBoxPolicy
+ > sub_divide;
+
+ template <typename InputCollection, typename Policy>
+ static inline void next_level(Box const& box,
+ InputCollection const& collection1,
+ index_vector_type const& input1,
+ InputCollection const& collection2,
+ index_vector_type const& input2,
+ int level, std::size_t min_elements,
+ Policy& policy, VisitBoxPolicy& box_policy)
+ {
+ if (boost::size(input1) > 0 && boost::size(input2) > 0)
+ {
+ if (std::size_t(boost::size(input1)) > min_elements
+ && std::size_t(boost::size(input2)) > min_elements
+ && level < 100)
+ {
+ sub_divide::apply(box, collection1, input1, collection2,
+ input2, level + 1, min_elements,
+ policy, box_policy);
+ }
+ else
+ {
+ box_policy.apply(box, level + 1);
+ handle_two(collection1, input1, collection2, input2, policy);
+ }
+ }
+ }
+
+public :
+ template <typename InputCollection, typename Policy>
+ static inline void apply(Box const& box,
+ InputCollection const& collection1, index_vector_type const& input1,
+ InputCollection const& collection2, index_vector_type const& input2,
+ int level,
+ std::size_t min_elements,
+ Policy& policy, VisitBoxPolicy& box_policy)
+ {
+ box_policy.apply(box, level);
+
+ Box lower_box, upper_box;
+ divide_box<Dimension>(box, lower_box, upper_box);
+
+ index_vector_type lower1, upper1, exceeding1;
+ index_vector_type lower2, upper2, exceeding2;
+ divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection1,
+ input1, lower1, upper1, exceeding1);
+ divide_into_subsets<OverlapsPolicy>(lower_box, upper_box, collection2,
+ input2, lower2, upper2, exceeding2);
+
+ if (boost::size(exceeding1) > 0)
+ {
+ // All exceeding from 1 with 2:
+ handle_two(collection1, exceeding1, collection2, exceeding2,
+ policy);
+
+ // All exceeding from 1 with lower and upper of 2:
+ handle_two(collection1, exceeding1, collection2, lower2, policy);
+ handle_two(collection1, exceeding1, collection2, upper2, policy);
+ }
+ if (boost::size(exceeding2) > 0)
+ {
+ // All exceeding from 2 with lower and upper of 1:
+ handle_two(collection1, lower1, collection2, exceeding2, policy);
+ handle_two(collection1, upper1, collection2, exceeding2, policy);
+ }
+
+ next_level(lower_box, collection1, lower1, collection2, lower2, level,
+ min_elements, policy, box_policy);
+ next_level(upper_box, collection1, upper1, collection2, upper2, level,
+ min_elements, policy, box_policy);
+ }
+};
+
+}} // namespace detail::partition
+
+struct visit_no_policy
+{
+ template <typename Box>
+ static inline void apply(Box const&, int )
+ {}
+};
+
+template
+<
+ typename Box,
+ typename ExpandPolicy,
+ typename OverlapsPolicy,
+ typename VisitBoxPolicy = visit_no_policy
+>
+class partition
+{
+ typedef std::vector<std::size_t> index_vector_type;
+
+ template <typename InputCollection>
+ static inline void expand_to_collection(InputCollection const& collection,
+ Box& total, index_vector_type& index_vector)
+ {
+ std::size_t index = 0;
+ for(typename boost::range_iterator<InputCollection const>::type it
+ = boost::begin(collection);
+ it != boost::end(collection);
+ ++it, ++index)
+ {
+ ExpandPolicy::apply(total, *it);
+ index_vector.push_back(index);
+ }
+ }
+
+public :
+ template <typename InputCollection, typename VisitPolicy>
+ static inline void apply(InputCollection const& collection,
+ VisitPolicy& visitor,
+ std::size_t min_elements = 16,
+ VisitBoxPolicy box_visitor = visit_no_policy()
+ )
+ {
+ if (std::size_t(boost::size(collection)) > min_elements)
+ {
+ index_vector_type index_vector;
+ Box total;
+ assign_inverse(total);
+ expand_to_collection(collection, total, index_vector);
+
+ detail::partition::partition_one_collection
+ <
+ 0, Box,
+ OverlapsPolicy,
+ VisitBoxPolicy
+ >::apply(total, collection, index_vector, 0, min_elements,
+ visitor, box_visitor);
+ }
+ else
+ {
+ typedef typename boost::range_iterator
+ <
+ InputCollection const
+ >::type iterator_type;
+ for(iterator_type it1 = boost::begin(collection);
+ it1 != boost::end(collection);
+ ++it1)
+ {
+ iterator_type it2 = it1;
+ for(++it2; it2 != boost::end(collection); ++it2)
+ {
+ visitor.apply(*it1, *it2);
+ }
+ }
+ }
+ }
+
+ template <typename InputCollection, typename VisitPolicy>
+ static inline void apply(InputCollection const& collection1,
+ InputCollection const& collection2,
+ VisitPolicy& visitor,
+ std::size_t min_elements = 16,
+ VisitBoxPolicy box_visitor = visit_no_policy()
+ )
+ {
+ if (std::size_t(boost::size(collection1)) > min_elements
+ && std::size_t(boost::size(collection2)) > min_elements)
+ {
+ index_vector_type index_vector1, index_vector2;
+ Box total;
+ assign_inverse(total);
+ expand_to_collection(collection1, total, index_vector1);
+ expand_to_collection(collection2, total, index_vector2);
+
+ detail::partition::partition_two_collections
+ <
+ 0, Box, OverlapsPolicy, VisitBoxPolicy
+ >::apply(total,
+ collection1, index_vector1,
+ collection2, index_vector2,
+ 0, min_elements, visitor, box_visitor);
+ }
+ else
+ {
+ typedef typename boost::range_iterator
+ <
+ InputCollection const
+ >::type iterator_type;
+ for(iterator_type it1 = boost::begin(collection1);
+ it1 != boost::end(collection1);
+ ++it1)
+ {
+ for(iterator_type it2 = boost::begin(collection2);
+ it2 != boost::end(collection2);
+ ++it2)
+ {
+ visitor.apply(*it1, *it2);
+ }
+ }
+ }
+ }
+
+};
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_PARTITION_HPP
diff --git a/src/boost/geometry/algorithms/detail/point_on_border.hpp b/src/boost/geometry/algorithms/detail/point_on_border.hpp
new file mode 100644
index 0000000..b7e15ba
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/point_on_border.hpp
@@ -0,0 +1,246 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.Dimension. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
+
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace point_on_border
+{
+
+
+template<typename Point>
+struct get_point
+{
+ static inline bool apply(Point& destination, Point const& source, bool)
+ {
+ destination = source;
+ return true;
+ }
+};
+
+template<typename Point, std::size_t Dimension, std::size_t DimensionCount>
+struct midpoint_helper
+{
+ template <typename InputPoint>
+ static inline bool apply(Point& p, InputPoint const& p1, InputPoint const& p2)
+ {
+ typename coordinate_type<Point>::type const two = 2;
+ set<Dimension>(p,
+ (get<Dimension>(p1) + get<Dimension>(p2)) / two);
+ return midpoint_helper<Point, Dimension + 1, DimensionCount>::apply(p, p1, p2);
+ }
+};
+
+
+template <typename Point, std::size_t DimensionCount>
+struct midpoint_helper<Point, DimensionCount, DimensionCount>
+{
+ template <typename InputPoint>
+ static inline bool apply(Point& , InputPoint const& , InputPoint const& )
+ {
+ return true;
+ }
+};
+
+
+template<typename Point, typename Range>
+struct point_on_range
+{
+ static inline bool apply(Point& point, Range const& range, bool midpoint)
+ {
+ const std::size_t n = boost::size(range);
+ if (midpoint && n > 1)
+ {
+ typedef typename boost::range_iterator
+ <
+ Range const
+ >::type iterator;
+
+ iterator it = boost::begin(range);
+ iterator prev = it++;
+ while (it != boost::end(range)
+ && detail::equals::equals_point_point(*it, *prev))
+ {
+ prev = it++;
+ }
+ if (it != boost::end(range))
+ {
+ return midpoint_helper
+ <
+ Point,
+ 0, dimension<Point>::value
+ >::apply(point, *prev, *it);
+ }
+ }
+
+ if (n > 0)
+ {
+ geometry::detail::conversion::convert_point_to_point(*boost::begin(range), point);
+ return true;
+ }
+ return false;
+ }
+};
+
+
+template<typename Point, typename Polygon>
+struct point_on_polygon
+{
+ static inline bool apply(Point& point, Polygon const& polygon, bool midpoint)
+ {
+ return point_on_range
+ <
+ Point,
+ typename ring_type<Polygon>::type
+ >::apply(point, exterior_ring(polygon), midpoint);
+ }
+};
+
+
+template<typename Point, typename Box>
+struct point_on_box
+{
+ static inline bool apply(Point& point, Box const& box, bool midpoint)
+ {
+ if (midpoint)
+ {
+ Point p1, p2;
+ detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, p1);
+ detail::assign::assign_box_2d_corner<max_corner, min_corner>(box, p2);
+ midpoint_helper
+ <
+ Point,
+ 0, dimension<Point>::value
+ >::apply(point, p1, p2);
+ }
+ else
+ {
+ detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
+ }
+
+ return true;
+ }
+};
+
+
+}} // namespace detail::point_on_border
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename GeometryTag,
+ typename Point,
+ typename Geometry
+
+>
+struct point_on_border
+{};
+
+
+template<typename Point>
+struct point_on_border<point_tag, Point, Point>
+ : detail::point_on_border::get_point<Point>
+{};
+
+
+template<typename Point, typename Linestring>
+struct point_on_border<linestring_tag, Point, Linestring>
+ : detail::point_on_border::point_on_range<Point, Linestring>
+{};
+
+
+template<typename Point, typename Ring>
+struct point_on_border<ring_tag, Point, Ring>
+ : detail::point_on_border::point_on_range<Point, Ring>
+{};
+
+
+template<typename Point, typename Polygon>
+struct point_on_border<polygon_tag, Point, Polygon>
+ : detail::point_on_border::point_on_polygon<Point, Polygon>
+{};
+
+
+template<typename Point, typename Box>
+struct point_on_border<box_tag, Point, Box>
+ : detail::point_on_border::point_on_box<Point, Box>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Take point on a border
+\ingroup overlay
+\tparam Geometry geometry type. This also defines the type of the output point
+\param point to assign
+\param geometry geometry to take point from
+\param midpoint boolean flag, true if the point should not be a vertex, but some point
+ in between of two vertices
+\return TRUE if successful, else false.
+ It is only false if polygon/line have no points
+\note for a polygon, it is always a point on the exterior ring
+\note for take_midpoint, it is not taken from two consecutive duplicate vertices,
+ (unless there are no other).
+ */
+template <typename Point, typename Geometry>
+inline bool point_on_border(Point& point,
+ Geometry const& geometry,
+ bool midpoint = false)
+{
+ concept::check<Point>();
+ concept::check<Geometry const>();
+
+ typedef typename point_type<Geometry>::type point_type;
+
+ return dispatch::point_on_border
+ <
+ typename tag<Geometry>::type,
+ Point,
+ Geometry
+ >::apply(point, geometry, midpoint);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
diff --git a/src/boost/geometry/algorithms/detail/ring_identifier.hpp b/src/boost/geometry/algorithms/detail/ring_identifier.hpp
new file mode 100644
index 0000000..9209ee0
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/ring_identifier.hpp
@@ -0,0 +1,70 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
+
+
+namespace boost { namespace geometry
+{
+
+
+// Ring Identifier. It is currently: source,multi,ring
+struct ring_identifier
+{
+
+ inline ring_identifier()
+ : source_index(-1)
+ , multi_index(-1)
+ , ring_index(-1)
+ {}
+
+ inline ring_identifier(int src, int mul, int rin)
+ : source_index(src)
+ , multi_index(mul)
+ , ring_index(rin)
+ {}
+
+ inline bool operator<(ring_identifier const& other) const
+ {
+ return source_index != other.source_index ? source_index < other.source_index
+ : multi_index !=other.multi_index ? multi_index < other.multi_index
+ : ring_index < other.ring_index
+ ;
+ }
+
+ inline bool operator==(ring_identifier const& other) const
+ {
+ return source_index == other.source_index
+ && ring_index == other.ring_index
+ && multi_index == other.multi_index
+ ;
+ }
+
+#if defined(BOOST_GEOMETRY_DEBUG_IDENTIFIER)
+ friend std::ostream& operator<<(std::ostream &os, ring_identifier const& ring_id)
+ {
+ os << "(s:" << ring_id.source_index;
+ if (ring_id.ring_index >= 0) os << ", r:" << ring_id.ring_index;
+ if (ring_id.multi_index >= 0) os << ", m:" << ring_id.multi_index;
+ os << ")";
+ return os;
+ }
+#endif
+
+
+ int source_index;
+ int multi_index;
+ int ring_index;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP
diff --git a/src/boost/geometry/algorithms/detail/sections/range_by_section.hpp b/src/boost/geometry/algorithms/detail/sections/range_by_section.hpp
new file mode 100644
index 0000000..ad62f23
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/sections/range_by_section.hpp
@@ -0,0 +1,131 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace section
+{
+
+
+template <typename Range, typename Section>
+struct full_section_range
+{
+ static inline Range const& apply(Range const& range, Section const& )
+ {
+ return range;
+ }
+};
+
+
+template <typename Polygon, typename Section>
+struct full_section_polygon
+{
+ static inline typename ring_return_type<Polygon const>::type apply(Polygon const& polygon, Section const& section)
+ {
+ return section.ring_id.ring_index < 0
+ ? geometry::exterior_ring(polygon)
+ : geometry::interior_rings(polygon)[section.ring_id.ring_index];
+ }
+};
+
+
+}} // namespace detail::section
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename Section
+>
+struct range_by_section
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename LineString, typename Section>
+struct range_by_section<linestring_tag, LineString, Section>
+ : detail::section::full_section_range<LineString, Section>
+{};
+
+
+template <typename Ring, typename Section>
+struct range_by_section<ring_tag, Ring, Section>
+ : detail::section::full_section_range<Ring, Section>
+{};
+
+
+template <typename Polygon, typename Section>
+struct range_by_section<polygon_tag, Polygon, Section>
+ : detail::section::full_section_polygon<Polygon, Section>
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+ \brief Get full ring (exterior, one of interiors, one from multi)
+ indicated by the specified section
+ \ingroup sectionalize
+ \tparam Geometry type
+ \tparam Section type of section to get from
+ \param geometry geometry to take section of
+ \param section structure with section
+ */
+template <typename Geometry, typename Section>
+inline typename ring_return_type<Geometry const>::type
+ range_by_section(Geometry const& geometry, Section const& section)
+{
+ concept::check<Geometry const>();
+
+ return dispatch::range_by_section
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Section
+ >::apply(geometry, section);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
diff --git a/src/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/src/boost/geometry/algorithms/detail/sections/sectionalize.hpp
new file mode 100644
index 0000000..a6e6837
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/sections/sectionalize.hpp
@@ -0,0 +1,648 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+
+#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/point_order.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+ \brief Structure containing section information
+ \details Section information consists of a bounding box, direction
+ information (if it is increasing or decreasing, per dimension),
+ index information (begin-end, ring, multi) and the number of
+ segments in this section
+
+ \tparam Box box-type
+ \tparam DimensionCount number of dimensions for this section
+ \ingroup sectionalize
+ */
+template <typename Box, std::size_t DimensionCount>
+struct section
+{
+ typedef Box box_type;
+
+ int id; // might be obsolete now, BSG 14-03-2011 TODO decide about this
+
+ int directions[DimensionCount];
+ ring_identifier ring_id;
+ Box bounding_box;
+
+ int begin_index;
+ int end_index;
+ std::size_t count;
+ std::size_t range_count;
+ bool duplicate;
+ int non_duplicate_index;
+
+ inline section()
+ : id(-1)
+ , begin_index(-1)
+ , end_index(-1)
+ , count(0)
+ , range_count(0)
+ , duplicate(false)
+ , non_duplicate_index(-1)
+ {
+ assign_inverse(bounding_box);
+ for (register std::size_t i = 0; i < DimensionCount; i++)
+ {
+ directions[i] = 0;
+ }
+ }
+};
+
+
+/*!
+ \brief Structure containing a collection of sections
+ \note Derived from a vector, proves to be faster than of deque
+ \note vector might be templated in the future
+ \ingroup sectionalize
+ */
+template <typename Box, std::size_t DimensionCount>
+struct sections : std::vector<section<Box, DimensionCount> >
+{
+ typedef Box box_type;
+ static std::size_t const value = DimensionCount;
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sectionalize
+{
+
+template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
+struct get_direction_loop
+{
+ typedef typename coordinate_type<Segment>::type coordinate_type;
+
+ static inline void apply(Segment const& seg,
+ int directions[DimensionCount])
+ {
+ coordinate_type const diff =
+ geometry::get<1, Dimension>(seg) - geometry::get<0, Dimension>(seg);
+
+ coordinate_type zero = coordinate_type();
+ directions[Dimension] = diff > zero ? 1 : diff < zero ? -1 : 0;
+
+ get_direction_loop
+ <
+ Segment, Dimension + 1, DimensionCount
+ >::apply(seg, directions);
+ }
+};
+
+template <typename Segment, std::size_t DimensionCount>
+struct get_direction_loop<Segment, DimensionCount, DimensionCount>
+{
+ static inline void apply(Segment const&, int [DimensionCount])
+ {}
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct copy_loop
+{
+ static inline void apply(T const source[DimensionCount],
+ T target[DimensionCount])
+ {
+ target[Dimension] = source[Dimension];
+ copy_loop<T, Dimension + 1, DimensionCount>::apply(source, target);
+ }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct copy_loop<T, DimensionCount, DimensionCount>
+{
+ static inline void apply(T const [DimensionCount], T [DimensionCount])
+ {}
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct compare_loop
+{
+ static inline bool apply(T const source[DimensionCount],
+ T const target[DimensionCount])
+ {
+ bool const not_equal = target[Dimension] != source[Dimension];
+
+ return not_equal
+ ? false
+ : compare_loop
+ <
+ T, Dimension + 1, DimensionCount
+ >::apply(source, target);
+ }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct compare_loop<T, DimensionCount, DimensionCount>
+{
+ static inline bool apply(T const [DimensionCount],
+ T const [DimensionCount])
+ {
+
+ return true;
+ }
+};
+
+
+template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
+struct check_duplicate_loop
+{
+ typedef typename coordinate_type<Segment>::type coordinate_type;
+
+ static inline bool apply(Segment const& seg)
+ {
+ if (! geometry::math::equals
+ (
+ geometry::get<0, Dimension>(seg),
+ geometry::get<1, Dimension>(seg)
+ )
+ )
+ {
+ return false;
+ }
+
+ return check_duplicate_loop
+ <
+ Segment, Dimension + 1, DimensionCount
+ >::apply(seg);
+ }
+};
+
+template <typename Segment, std::size_t DimensionCount>
+struct check_duplicate_loop<Segment, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Segment const&)
+ {
+ return true;
+ }
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct assign_loop
+{
+ static inline void apply(T dims[DimensionCount], int const value)
+ {
+ dims[Dimension] = value;
+ assign_loop<T, Dimension + 1, DimensionCount>::apply(dims, value);
+ }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct assign_loop<T, DimensionCount, DimensionCount>
+{
+ static inline void apply(T [DimensionCount], int const)
+ {
+ }
+};
+
+/// @brief Helper class to create sections of a part of a range, on the fly
+template
+<
+ typename Range, // Can be closeable_view
+ typename Point,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize_part
+{
+ typedef model::referring_segment<Point const> segment_type;
+ typedef typename boost::range_value<Sections>::type section_type;
+
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ static inline void apply(Sections& sections, section_type& section,
+ int& index, int& ndi,
+ Range const& range,
+ ring_identifier ring_id)
+ {
+ if (int(boost::size(range)) <= index)
+ {
+ return;
+ }
+
+ if (index == 0)
+ {
+ ndi = 0;
+ }
+
+ iterator_type it = boost::begin(range);
+ it += index;
+
+ for(iterator_type previous = it++;
+ it != boost::end(range);
+ ++previous, ++it, index++)
+ {
+ segment_type segment(*previous, *it);
+
+ int direction_classes[DimensionCount] = {0};
+ get_direction_loop
+ <
+ segment_type, 0, DimensionCount
+ >::apply(segment, direction_classes);
+
+ // if "dir" == 0 for all point-dimensions, it is duplicate.
+ // Those sections might be omitted, if wished, lateron
+ bool duplicate = false;
+
+ if (direction_classes[0] == 0)
+ {
+ // Recheck because ALL dimensions should be checked,
+ // not only first one.
+ // (DimensionCount might be < dimension<P>::value)
+ if (check_duplicate_loop
+ <
+ segment_type, 0, geometry::dimension<Point>::type::value
+ >::apply(segment)
+ )
+ {
+ duplicate = true;
+
+ // Change direction-info to force new section
+ // Note that wo consecutive duplicate segments will generate
+ // only one duplicate-section.
+ // Actual value is not important as long as it is not -1,0,1
+ assign_loop
+ <
+ int, 0, DimensionCount
+ >::apply(direction_classes, -99);
+ }
+ }
+
+ if (section.count > 0
+ && (!compare_loop
+ <
+ int, 0, DimensionCount
+ >::apply(direction_classes, section.directions)
+ || section.count > MaxCount
+ )
+ )
+ {
+ sections.push_back(section);
+ section = section_type();
+ }
+
+ if (section.count == 0)
+ {
+ section.begin_index = index;
+ section.ring_id = ring_id;
+ section.duplicate = duplicate;
+ section.non_duplicate_index = ndi;
+ section.range_count = boost::size(range);
+
+ copy_loop
+ <
+ int, 0, DimensionCount
+ >::apply(direction_classes, section.directions);
+ geometry::expand(section.bounding_box, *previous);
+ }
+
+ geometry::expand(section.bounding_box, *it);
+ section.end_index = index + 1;
+ section.count++;
+ if (! duplicate)
+ {
+ ndi++;
+ }
+ }
+ }
+};
+
+
+template
+<
+ typename Range, closure_selector Closure, bool Reverse,
+ typename Point,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize_range
+{
+ typedef typename closeable_view<Range const, Closure>::type cview_type;
+ typedef typename reversible_view
+ <
+ cview_type const,
+ Reverse ? iterate_reverse : iterate_forward
+ >::type view_type;
+
+ static inline void apply(Range const& range, Sections& sections,
+ ring_identifier ring_id)
+ {
+ typedef model::referring_segment<Point const> segment_type;
+
+ cview_type cview(range);
+ view_type view(cview);
+
+ std::size_t const n = boost::size(view);
+ if (n == 0)
+ {
+ // Zero points, no section
+ return;
+ }
+
+ if (n == 1)
+ {
+ // Line with one point ==> no sections
+ return;
+ }
+
+ int index = 0;
+ int ndi = 0; // non duplicate index
+
+ typedef typename boost::range_value<Sections>::type section_type;
+ section_type section;
+
+ sectionalize_part
+ <
+ view_type, Point, Sections,
+ DimensionCount, MaxCount
+ >::apply(sections, section, index, ndi,
+ view, ring_id);
+
+ // Add last section if applicable
+ if (section.count > 0)
+ {
+ sections.push_back(section);
+ }
+ }
+};
+
+template
+<
+ typename Polygon,
+ bool Reverse,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize_polygon
+{
+ static inline void apply(Polygon const& poly, Sections& sections,
+ ring_identifier ring_id)
+ {
+ typedef typename point_type<Polygon>::type point_type;
+ typedef typename ring_type<Polygon>::type ring_type;
+ typedef sectionalize_range
+ <
+ ring_type, closure<Polygon>::value, Reverse,
+ point_type, Sections, DimensionCount, MaxCount
+ > sectionalizer_type;
+
+ ring_id.ring_index = -1;
+ sectionalizer_type::apply(exterior_ring(poly), sections, ring_id);//-1, multi_index);
+
+ ring_id.ring_index++;
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings);
+ ++it, ++ring_id.ring_index)
+ {
+ sectionalizer_type::apply(*it, sections, ring_id);
+ }
+ }
+};
+
+template
+<
+ typename Box,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize_box
+{
+ static inline void apply(Box const& box, Sections& sections, ring_identifier const& ring_id)
+ {
+ typedef typename point_type<Box>::type point_type;
+
+ assert_dimension<Box, 2>();
+
+ // Add all four sides of the 2D-box as separate section.
+ // Easiest is to convert it to a polygon.
+ // However, we don't have the polygon type
+ // (or polygon would be a helper-type).
+ // Therefore we mimic a linestring/std::vector of 5 points
+
+ // TODO: might be replaced by assign_box_corners_oriented
+ // or just "convert"
+ point_type ll, lr, ul, ur;
+ geometry::detail::assign_box_corners(box, ll, lr, ul, ur);
+
+ std::vector<point_type> points;
+ points.push_back(ll);
+ points.push_back(ul);
+ points.push_back(ur);
+ points.push_back(lr);
+ points.push_back(ll);
+
+ sectionalize_range
+ <
+ std::vector<point_type>, closed, false,
+ point_type,
+ Sections,
+ DimensionCount,
+ MaxCount
+ >::apply(points, sections, ring_id);
+ }
+};
+
+template <typename Sections>
+inline void set_section_unique_ids(Sections& sections)
+{
+ // Set ID's.
+ int index = 0;
+ for (typename boost::range_iterator<Sections>::type it = boost::begin(sections);
+ it != boost::end(sections);
+ ++it)
+ {
+ it->id = index++;
+ }
+}
+
+
+}} // namespace detail::sectionalize
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ bool Reverse,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+template
+<
+ typename Box,
+ bool Reverse,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize<box_tag, Box, Reverse, Sections, DimensionCount, MaxCount>
+ : detail::sectionalize::sectionalize_box
+ <
+ Box,
+ Sections,
+ DimensionCount,
+ MaxCount
+ >
+{};
+
+template
+<
+ typename LineString,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize
+ <
+ linestring_tag,
+ LineString,
+ false,
+ Sections,
+ DimensionCount,
+ MaxCount
+ >
+ : detail::sectionalize::sectionalize_range
+ <
+ LineString, closed, false,
+ typename point_type<LineString>::type,
+ Sections,
+ DimensionCount,
+ MaxCount
+ >
+{};
+
+template
+<
+ typename Ring,
+ bool Reverse,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize<ring_tag, Ring, Reverse, Sections, DimensionCount, MaxCount>
+ : detail::sectionalize::sectionalize_range
+ <
+ Ring, geometry::closure<Ring>::value, Reverse,
+ typename point_type<Ring>::type,
+ Sections,
+ DimensionCount,
+ MaxCount
+ >
+{};
+
+template
+<
+ typename Polygon,
+ bool Reverse,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize<polygon_tag, Polygon, Reverse, Sections, DimensionCount, MaxCount>
+ : detail::sectionalize::sectionalize_polygon
+ <
+ Polygon, Reverse, Sections, DimensionCount, MaxCount
+ >
+{};
+
+} // namespace dispatch
+#endif
+
+
+/*!
+ \brief Split a geometry into monotonic sections
+ \ingroup sectionalize
+ \tparam Geometry type of geometry to check
+ \tparam Sections type of sections to create
+ \param geometry geometry to create sections from
+ \param sections structure with sections
+ \param source_index index to assign to the ring_identifiers
+ */
+template<bool Reverse, typename Geometry, typename Sections>
+inline void sectionalize(Geometry const& geometry, Sections& sections, int source_index = 0)
+{
+ concept::check<Geometry const>();
+
+ // TODO: review use of this constant (see below) as causing problems with GCC 4.6 --mloskot
+ // A maximum of 10 segments per section seems to give the fastest results
+ //static std::size_t const max_segments_per_section = 10;
+ typedef dispatch::sectionalize
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Reverse,
+ Sections,
+ Sections::value,
+ 10 // TODO: max_segments_per_section
+ > sectionalizer_type;
+
+ sections.clear();
+ ring_identifier ring_id;
+ ring_id.source_index = source_index;
+ sectionalizer_type::apply(geometry, sections, ring_id);
+ detail::sectionalize::set_section_unique_ids(sections);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
diff --git a/src/boost/geometry/algorithms/detail/throw_on_empty_input.hpp b/src/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
new file mode 100644
index 0000000..62328a0
--- /dev/null
+++ b/src/boost/geometry/algorithms/detail/throw_on_empty_input.hpp
@@ -0,0 +1,53 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
+
+#include <boost/geometry/core/exception.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+
+// BSG 2012-02-06: we use this currently only for distance.
+// For other scalar results area,length,perimeter it is commented on purpose.
+// Reason is that for distance there is no other choice. distance of two
+// empty geometries (or one empty) should NOT return any value.
+// But for area it is no problem to be 0.
+// Suppose: area(intersection(a,b)). We (probably) don't want a throw there...
+
+// So decided that at least for Boost 1.49 this is commented for
+// scalar results, except distance.
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Geometry>
+inline void throw_on_empty_input(Geometry const& geometry)
+{
+#if ! defined(BOOST_GEOMETRY_EMPTY_INPUT_NO_THROW)
+ if (geometry::num_points(geometry) == 0)
+ {
+ throw empty_input_exception();
+ }
+#endif
+}
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_THROW_ON_EMPTY_INPUT_HPP
+
diff --git a/src/boost/geometry/algorithms/difference.hpp b/src/boost/geometry/algorithms/difference.hpp
new file mode 100644
index 0000000..480dd92
--- /dev/null
+++ b/src/boost/geometry/algorithms/difference.hpp
@@ -0,0 +1,160 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
+
+#include <algorithm>
+
+#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace difference
+{
+
+/*!
+\brief_calc2{difference} \brief_strategy
+\ingroup difference
+\details \details_calc2{difference_insert, spatial set theoretic difference}
+ \brief_strategy. \details_inserter{difference}
+\tparam GeometryOut output geometry type, must be specified
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam OutputIterator output iterator
+\tparam Strategy \tparam_strategy_overlay
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param out \param_out{difference}
+\param strategy \param_strategy{difference}
+\return \return_out
+
+\qbk{distinguish,with strategy}
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator,
+ typename Strategy
+>
+inline OutputIterator difference_insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2, OutputIterator out,
+ Strategy const& strategy)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ concept::check<GeometryOut>();
+
+ return geometry::dispatch::intersection_insert
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type,
+ typename geometry::tag<GeometryOut>::type,
+ geometry::is_areal<Geometry1>::value,
+ geometry::is_areal<Geometry2>::value,
+ geometry::is_areal<GeometryOut>::value,
+ Geometry1, Geometry2,
+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value,
+ geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
+ OutputIterator, GeometryOut,
+ overlay_difference,
+ Strategy
+ >::apply(geometry1, geometry2, out, strategy);
+}
+
+/*!
+\brief_calc2{difference}
+\ingroup difference
+\details \details_calc2{difference_insert, spatial set theoretic difference}.
+ \details_insert{difference}
+\tparam GeometryOut output geometry type, must be specified
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam OutputIterator output iterator
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param out \param_out{difference}
+\return \return_out
+
+\qbk{[include reference/algorithms/difference_insert.qbk]}
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator
+>
+inline OutputIterator difference_insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2, OutputIterator out)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ concept::check<GeometryOut>();
+
+ typedef strategy_intersection
+ <
+ typename cs_tag<GeometryOut>::type,
+ Geometry1,
+ Geometry2,
+ typename geometry::point_type<GeometryOut>::type
+ > strategy;
+
+ return difference_insert<GeometryOut>(geometry1, geometry2,
+ out, strategy());
+}
+
+
+}} // namespace detail::difference
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+/*!
+\brief_calc2{difference}
+\ingroup difference
+\details \details_calc2{difference, spatial set theoretic difference}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Collection \tparam_output_collection
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param output_collection the output collection
+
+\qbk{[include reference/algorithms/difference.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Collection
+>
+inline void difference(Geometry1 const& geometry1,
+ Geometry2 const& geometry2, Collection& output_collection)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ typedef typename boost::range_value<Collection>::type geometry_out;
+ concept::check<geometry_out>();
+
+ detail::difference::difference_insert<geometry_out>(
+ geometry1, geometry2,
+ std::back_inserter(output_collection));
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP
diff --git a/src/boost/geometry/algorithms/disjoint.hpp b/src/boost/geometry/algorithms/disjoint.hpp
new file mode 100644
index 0000000..f986cc2
--- /dev/null
+++ b/src/boost/geometry/algorithms/disjoint.hpp
@@ -0,0 +1,301 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DISJOINT_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISJOINT_HPP
+
+#include <cstddef>
+#include <deque>
+
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+
+#include <boost/static_assert.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/reverse_dispatch.hpp>
+
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/for_each_range.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace disjoint
+{
+
+template<typename Geometry>
+struct check_each_ring_for_within
+{
+ bool has_within;
+ Geometry const& m_geometry;
+
+ inline check_each_ring_for_within(Geometry const& g)
+ : has_within(false)
+ , m_geometry(g)
+ {}
+
+ template <typename Range>
+ inline void apply(Range const& range)
+ {
+ typename geometry::point_type<Range>::type p;
+ geometry::point_on_border(p, range);
+ if (geometry::within(p, m_geometry))
+ {
+ has_within = true;
+ }
+ }
+};
+
+template <typename FirstGeometry, typename SecondGeometry>
+inline bool rings_containing(FirstGeometry const& geometry1,
+ SecondGeometry const& geometry2)
+{
+ check_each_ring_for_within<FirstGeometry> checker(geometry1);
+ geometry::detail::for_each_range(geometry2, checker);
+ return checker.has_within;
+}
+
+
+struct assign_disjoint_policy
+{
+ // We want to include all points:
+ static bool const include_no_turn = true;
+ static bool const include_degenerate = true;
+ static bool const include_opposite = true;
+
+ // We don't assign extra info:
+ template
+ <
+ typename Info,
+ typename Point1,
+ typename Point2,
+ typename IntersectionInfo,
+ typename DirInfo
+ >
+ static inline void apply(Info& , Point1 const& , Point2 const&,
+ IntersectionInfo const&, DirInfo const&)
+ {}
+};
+
+
+template <typename Geometry1, typename Geometry2>
+struct disjoint_linear
+{
+ static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ {
+ typedef typename geometry::point_type<Geometry1>::type point_type;
+
+ typedef overlay::turn_info<point_type> turn_info;
+ std::deque<turn_info> turns;
+
+ // Specify two policies:
+ // 1) Stop at any intersection
+ // 2) In assignment, include also degenerate points (which are normally skipped)
+ disjoint_interrupt_policy policy;
+ geometry::get_turns
+ <
+ false, false,
+ assign_disjoint_policy
+ >(geometry1, geometry2, turns, policy);
+ if (policy.has_intersections)
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+template <typename Segment1, typename Segment2>
+struct disjoint_segment
+{
+ static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
+ {
+ typedef typename point_type<Segment1>::type point_type;
+
+ segment_intersection_points<point_type> is
+ = strategy::intersection::relate_cartesian_segments
+ <
+ policies::relate::segments_intersection_points
+ <
+ Segment1,
+ Segment2,
+ segment_intersection_points<point_type>
+ >
+ >::apply(segment1, segment2);
+
+ return is.count == 0;
+ }
+};
+
+template <typename Geometry1, typename Geometry2>
+struct general_areal
+{
+ static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ {
+ if (! disjoint_linear<Geometry1, Geometry2>::apply(geometry1, geometry2))
+ {
+ return false;
+ }
+
+ // If there is no intersection of segments, they might located
+ // inside each other
+ if (rings_containing(geometry1, geometry2)
+ || rings_containing(geometry2, geometry1))
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+
+}} // namespace detail::disjoint
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename GeometryTag1, typename GeometryTag2,
+ typename Geometry1, typename Geometry2,
+ std::size_t DimensionCount
+>
+struct disjoint
+ : detail::disjoint::general_areal<Geometry1, Geometry2>
+{};
+
+
+template <typename Point1, typename Point2, std::size_t DimensionCount>
+struct disjoint<point_tag, point_tag, Point1, Point2, DimensionCount>
+ : detail::disjoint::point_point<Point1, Point2, 0, DimensionCount>
+{};
+
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct disjoint<box_tag, box_tag, Box1, Box2, DimensionCount>
+ : detail::disjoint::box_box<Box1, Box2, 0, DimensionCount>
+{};
+
+
+template <typename Point, typename Box, std::size_t DimensionCount>
+struct disjoint<point_tag, box_tag, Point, Box, DimensionCount>
+ : detail::disjoint::point_box<Point, Box, 0, DimensionCount>
+{};
+
+template <typename Linestring1, typename Linestring2>
+struct disjoint<linestring_tag, linestring_tag, Linestring1, Linestring2, 2>
+ : detail::disjoint::disjoint_linear<Linestring1, Linestring2>
+{};
+
+template <typename Linestring1, typename Linestring2>
+struct disjoint<segment_tag, segment_tag, Linestring1, Linestring2, 2>
+ : detail::disjoint::disjoint_segment<Linestring1, Linestring2>
+{};
+
+template <typename Linestring, typename Segment>
+struct disjoint<linestring_tag, segment_tag, Linestring, Segment, 2>
+ : detail::disjoint::disjoint_linear<Linestring, Segment>
+{};
+
+
+template
+<
+ typename GeometryTag1, typename GeometryTag2,
+ typename Geometry1, typename Geometry2,
+ std::size_t DimensionCount
+>
+struct disjoint_reversed
+{
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ {
+ return disjoint
+ <
+ GeometryTag2, GeometryTag1,
+ Geometry2, Geometry1,
+ DimensionCount
+ >::apply(g2, g1);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+\brief \brief_check2{are disjoint}
+\ingroup disjoint
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return \return_check2{are disjoint}
+
+\qbk{[include reference/algorithms/disjoint.qbk]}
+*/
+template <typename Geometry1, typename Geometry2>
+inline bool disjoint(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
+{
+ concept::check_concepts_and_equal_dimensions
+ <
+ Geometry1 const,
+ Geometry2 const
+ >();
+
+ return boost::mpl::if_c
+ <
+ reverse_dispatch<Geometry1, Geometry2>::type::value,
+ dispatch::disjoint_reversed
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ dimension<Geometry1>::type::value
+ >,
+ dispatch::disjoint
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ dimension<Geometry1>::type::value
+ >
+ >::type::apply(geometry1, geometry2);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISJOINT_HPP
diff --git a/src/boost/geometry/algorithms/distance.hpp b/src/boost/geometry/algorithms/distance.hpp
new file mode 100644
index 0000000..11c2bc9
--- /dev/null
+++ b/src/boost/geometry/algorithms/distance.hpp
@@ -0,0 +1,591 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/reverse_dispatch.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/algorithms/not_implemented.hpp>
+#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
+
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/default_distance_result.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+// To avoid spurious namespaces here:
+using strategy::distance::services::return_type;
+
+template <typename P1, typename P2, typename Strategy>
+struct point_to_point
+{
+ static inline typename return_type<Strategy>::type apply(P1 const& p1,
+ P2 const& p2, Strategy const& strategy)
+ {
+ return strategy.apply(p1, p2);
+ }
+};
+
+
+template<typename Point, typename Segment, typename Strategy>
+struct point_to_segment
+{
+ static inline typename return_type<Strategy>::type apply(Point const& point,
+ Segment const& segment, Strategy const& )
+ {
+ typename strategy::distance::services::default_strategy
+ <
+ segment_tag,
+ Point,
+ typename point_type<Segment>::type,
+ typename cs_tag<Point>::type,
+ typename cs_tag<typename point_type<Segment>::type>::type,
+ Strategy
+ >::type segment_strategy;
+
+ typename point_type<Segment>::type p[2];
+ geometry::detail::assign_point_from_index<0>(segment, p[0]);
+ geometry::detail::assign_point_from_index<1>(segment, p[1]);
+ return segment_strategy.apply(point, p[0], p[1]);
+ }
+};
+
+
+template
+<
+ typename Point,
+ typename Range,
+ closure_selector Closure,
+ typename PPStrategy,
+ typename PSStrategy
+>
+struct point_to_range
+{
+ typedef typename return_type<PSStrategy>::type return_type;
+
+ static inline return_type apply(Point const& point, Range const& range,
+ PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
+ {
+ return_type const zero = return_type(0);
+
+ if (boost::size(range) == 0)
+ {
+ return zero;
+ }
+
+ typedef typename closeable_view<Range const, Closure>::type view_type;
+
+ view_type view(range);
+
+ // line of one point: return point distance
+ typedef typename boost::range_iterator<view_type const>::type iterator_type;
+ iterator_type it = boost::begin(view);
+ iterator_type prev = it++;
+ if (it == boost::end(view))
+ {
+ return pp_strategy.apply(point, *boost::begin(view));
+ }
+
+ // Create comparable (more efficient) strategy
+ typedef typename strategy::distance::services::comparable_type<PSStrategy>::type eps_strategy_type;
+ eps_strategy_type eps_strategy = strategy::distance::services::get_comparable<PSStrategy>::apply(ps_strategy);
+
+ // start with first segment distance
+ return_type d = eps_strategy.apply(point, *prev, *it);
+ return_type rd = ps_strategy.apply(point, *prev, *it);
+
+ // check if other segments are closer
+ for (++prev, ++it; it != boost::end(view); ++prev, ++it)
+ {
+ return_type const ds = eps_strategy.apply(point, *prev, *it);
+ if (geometry::math::equals(ds, zero))
+ {
+ return ds;
+ }
+ else if (ds < d)
+ {
+ d = ds;
+ rd = ps_strategy.apply(point, *prev, *it);
+ }
+ }
+
+ return rd;
+ }
+};
+
+
+template
+<
+ typename Point,
+ typename Ring,
+ closure_selector Closure,
+ typename PPStrategy,
+ typename PSStrategy
+>
+struct point_to_ring
+{
+ typedef std::pair
+ <
+ typename return_type<PPStrategy>::type, bool
+ > distance_containment;
+
+ static inline distance_containment apply(Point const& point,
+ Ring const& ring,
+ PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
+ {
+ return distance_containment
+ (
+ point_to_range
+ <
+ Point,
+ Ring,
+ Closure,
+ PPStrategy,
+ PSStrategy
+ >::apply(point, ring, pp_strategy, ps_strategy),
+ geometry::within(point, ring)
+ );
+ }
+};
+
+
+
+template
+<
+ typename Point,
+ typename Polygon,
+ closure_selector Closure,
+ typename PPStrategy,
+ typename PSStrategy
+>
+struct point_to_polygon
+{
+ typedef typename return_type<PPStrategy>::type return_type;
+ typedef std::pair<return_type, bool> distance_containment;
+
+ static inline distance_containment apply(Point const& point,
+ Polygon const& polygon,
+ PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
+ {
+ // Check distance to all rings
+ typedef point_to_ring
+ <
+ Point,
+ typename ring_type<Polygon>::type,
+ Closure,
+ PPStrategy,
+ PSStrategy
+ > per_ring;
+
+ distance_containment dc = per_ring::apply(point,
+ exterior_ring(polygon), pp_strategy, ps_strategy);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ distance_containment dcr = per_ring::apply(point,
+ *it, pp_strategy, ps_strategy);
+ if (dcr.first < dc.first)
+ {
+ dc.first = dcr.first;
+ }
+ // If it was inside, and also inside inner ring,
+ // turn off the inside-flag, it is outside the polygon
+ if (dc.second && dcr.second)
+ {
+ dc.second = false;
+ }
+ }
+ return dc;
+ }
+};
+
+
+// Helper metafunction for default strategy retrieval
+template <typename Geometry1, typename Geometry2>
+struct default_strategy
+ : strategy::distance::services::default_strategy
+ <
+ point_tag,
+ typename point_type<Geometry1>::type,
+ typename point_type<Geometry2>::type
+ >
+{};
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+using strategy::distance::services::return_type;
+
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename Strategy = typename detail::distance::default_strategy<Geometry1, Geometry2>::type,
+ typename Tag1 = typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
+ typename Tag2 = typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
+ typename StrategyTag = typename strategy::distance::services::tag<Strategy>::type,
+ bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
+>
+struct distance: not_implemented<Tag1, Tag2>
+{};
+
+
+// If reversal is needed, perform it
+template
+<
+ typename Geometry1, typename Geometry2, typename Strategy,
+ typename Tag1, typename Tag2, typename StrategyTag
+>
+struct distance
+<
+ Geometry1, Geometry2, Strategy,
+ Tag1, Tag2, StrategyTag,
+ true
+>
+ : distance<Geometry2, Geometry1, Strategy, Tag2, Tag1, StrategyTag, false>
+{
+ static inline typename return_type<Strategy>::type apply(
+ Geometry1 const& g1,
+ Geometry2 const& g2,
+ Strategy const& strategy)
+ {
+ return distance
+ <
+ Geometry2, Geometry1, Strategy,
+ Tag2, Tag1, StrategyTag,
+ false
+ >::apply(g2, g1, strategy);
+ }
+};
+
+// If reversal is needed and we got the strategy by default, invert it before
+// proceeding to the reversal.
+template
+<
+ typename Geometry1, typename Geometry2,
+ typename Tag1, typename Tag2, typename StrategyTag
+>
+struct distance
+<
+ Geometry1, Geometry2,
+ typename detail::distance::default_strategy<Geometry1, Geometry2>::type,
+ Tag1, Tag2, StrategyTag,
+ true
+>
+ : distance
+ <
+ Geometry2, Geometry1,
+ typename detail::distance::default_strategy<Geometry2, Geometry1>::type,
+ Tag2, Tag1, StrategyTag,
+ false
+ >
+{
+ typedef typename detail::distance::default_strategy<Geometry2, Geometry1>::type reversed_strategy;
+
+ static inline typename strategy::distance::services::return_type<reversed_strategy>::type apply(
+ Geometry1 const& g1,
+ Geometry2 const& g2,
+ typename detail::distance::default_strategy<Geometry1, Geometry2>::type const&)
+ {
+ return distance
+ <
+ Geometry2, Geometry1, reversed_strategy,
+ Tag2, Tag1, StrategyTag,
+ false
+ >::apply(g2, g1, reversed_strategy());
+ }
+};
+
+
+// Point-point
+template <typename P1, typename P2, typename Strategy>
+struct distance
+ <
+ P1, P2, Strategy,
+ point_tag, point_tag, strategy_tag_distance_point_point,
+ false
+ >
+ : detail::distance::point_to_point<P1, P2, Strategy>
+{};
+
+
+// Point-line version 1, where point-point strategy is specified
+template <typename Point, typename Linestring, typename Strategy>
+struct distance
+<
+ Point, Linestring, Strategy,
+ point_tag, linestring_tag, strategy_tag_distance_point_point,
+ false
+>
+{
+
+ static inline typename return_type<Strategy>::type apply(Point const& point,
+ Linestring const& linestring,
+ Strategy const& strategy)
+ {
+ typedef typename strategy::distance::services::default_strategy
+ <
+ segment_tag,
+ Point,
+ typename point_type<Linestring>::type
+ >::type ps_strategy_type;
+
+ return detail::distance::point_to_range
+ <
+ Point, Linestring, closed, Strategy, ps_strategy_type
+ >::apply(point, linestring, strategy, ps_strategy_type());
+ }
+};
+
+
+// Point-line version 2, where point-segment strategy is specified
+template <typename Point, typename Linestring, typename Strategy>
+struct distance
+<
+ Point, Linestring, Strategy,
+ point_tag, linestring_tag, strategy_tag_distance_point_segment,
+ false
+>
+{
+ static inline typename return_type<Strategy>::type apply(Point const& point,
+ Linestring const& linestring,
+ Strategy const& strategy)
+ {
+ typedef typename Strategy::point_strategy_type pp_strategy_type;
+ return detail::distance::point_to_range
+ <
+ Point, Linestring, closed, pp_strategy_type, Strategy
+ >::apply(point, linestring, pp_strategy_type(), strategy);
+ }
+};
+
+// Point-ring , where point-segment strategy is specified
+template <typename Point, typename Ring, typename Strategy>
+struct distance
+<
+ Point, Ring, Strategy,
+ point_tag, ring_tag, strategy_tag_distance_point_point,
+ false
+>
+{
+ typedef typename return_type<Strategy>::type return_type;
+
+ static inline return_type apply(Point const& point,
+ Ring const& ring,
+ Strategy const& strategy)
+ {
+ typedef typename strategy::distance::services::default_strategy
+ <
+ segment_tag,
+ Point,
+ typename point_type<Ring>::type
+ >::type ps_strategy_type;
+
+ std::pair<return_type, bool>
+ dc = detail::distance::point_to_ring
+ <
+ Point, Ring,
+ geometry::closure<Ring>::value,
+ Strategy, ps_strategy_type
+ >::apply(point, ring, strategy, ps_strategy_type());
+
+ return dc.second ? return_type(0) : dc.first;
+ }
+};
+
+
+// Point-polygon , where point-segment strategy is specified
+template <typename Point, typename Polygon, typename Strategy>
+struct distance
+<
+ Point, Polygon, Strategy,
+ point_tag, polygon_tag, strategy_tag_distance_point_point,
+ false
+>
+{
+ typedef typename return_type<Strategy>::type return_type;
+
+ static inline return_type apply(Point const& point,
+ Polygon const& polygon,
+ Strategy const& strategy)
+ {
+ typedef typename strategy::distance::services::default_strategy
+ <
+ segment_tag,
+ Point,
+ typename point_type<Polygon>::type
+ >::type ps_strategy_type;
+
+ std::pair<return_type, bool>
+ dc = detail::distance::point_to_polygon
+ <
+ Point, Polygon,
+ geometry::closure<Polygon>::value,
+ Strategy, ps_strategy_type
+ >::apply(point, polygon, strategy, ps_strategy_type());
+
+ return dc.second ? return_type(0) : dc.first;
+ }
+};
+
+
+
+// Point-segment version 1, with point-point strategy
+template <typename Point, typename Segment, typename Strategy>
+struct distance
+<
+ Point, Segment, Strategy,
+ point_tag, segment_tag, strategy_tag_distance_point_point,
+ false
+> : detail::distance::point_to_segment<Point, Segment, Strategy>
+{};
+
+// Point-segment version 2, with point-segment strategy
+template <typename Point, typename Segment, typename Strategy>
+struct distance
+<
+ Point, Segment, Strategy,
+ point_tag, segment_tag, strategy_tag_distance_point_segment,
+ false
+>
+{
+ static inline typename return_type<Strategy>::type apply(Point const& point,
+ Segment const& segment, Strategy const& strategy)
+ {
+
+ typename point_type<Segment>::type p[2];
+ geometry::detail::assign_point_from_index<0>(segment, p[0]);
+ geometry::detail::assign_point_from_index<1>(segment, p[1]);
+ return strategy.apply(point, p[0], p[1]);
+ }
+};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+\brief \brief_calc2{distance} \brief_strategy
+\ingroup distance
+\details
+\details \details_calc{area}. \brief_strategy. \details_strategy_reasons
+
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy{Distance}
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy \param_strategy{distance}
+\return \return_calc{distance}
+\note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
+ it may also be a point-segment strategy.
+
+\qbk{distinguish,with strategy}
+
+\qbk{
+[heading Available Strategies]
+\* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)]
+\* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)]
+\* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)]
+\* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)]
+\* more (currently extensions): Vincenty\, Andoyer (geographic)
+}
+ */
+
+/*
+Note, in case of a Compilation Error:
+if you get:
+ - "Failed to specialize function template ..."
+ - "error: no matching function for call to ..."
+for distance, it is probably so that there is no specialization
+for return_type<...> for your strategy.
+*/
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline typename strategy::distance::services::return_type<Strategy>::type distance(
+ Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ detail::throw_on_empty_input(geometry1);
+ detail::throw_on_empty_input(geometry2);
+
+ return dispatch::distance
+ <
+ Geometry1,
+ Geometry2,
+ Strategy
+ >::apply(geometry1, geometry2, strategy);
+}
+
+
+/*!
+\brief \brief_calc2{distance}
+\ingroup distance
+\details The default strategy is used, corresponding to the coordinate system of the geometries
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return \return_calc{distance}
+
+\qbk{[include reference/algorithms/distance.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline typename default_distance_result<Geometry1, Geometry2>::type distance(
+ Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ return distance(geometry1, geometry2,
+ typename detail::distance::default_strategy<Geometry1, Geometry2>::type());
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP
diff --git a/src/boost/geometry/algorithms/envelope.hpp b/src/boost/geometry/algorithms/envelope.hpp
new file mode 100644
index 0000000..da34f6a
--- /dev/null
+++ b/src/boost/geometry/algorithms/envelope.hpp
@@ -0,0 +1,273 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+
+/// Calculate envelope of an 2D or 3D segment
+template<typename Geometry, typename Box>
+struct envelope_expand_one
+{
+ static inline void apply(Geometry const& geometry, Box& mbr)
+ {
+ assign_inverse(mbr);
+ geometry::expand(mbr, geometry);
+ }
+};
+
+
+/// Iterate through range (also used in multi*)
+template<typename Range, typename Box>
+inline void envelope_range_additional(Range const& range, Box& mbr)
+{
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ for (iterator_type it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ geometry::expand(mbr, *it);
+ }
+}
+
+
+
+/// Generic range dispatching struct
+template <typename Range, typename Box>
+struct envelope_range
+{
+ /// Calculate envelope of range using a strategy
+ static inline void apply(Range const& range, Box& mbr)
+ {
+ assign_inverse(mbr);
+ envelope_range_additional(range, mbr);
+ }
+};
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Note, the strategy is for future use (less/greater -> compare spherical
+// using other methods), defaults are OK for now.
+// However, they are already in the template methods
+
+template
+<
+ typename Tag1, typename Tag2,
+ typename Geometry, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template
+<
+ typename Point, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+ <
+ point_tag, box_tag,
+ Point, Box,
+ StrategyLess, StrategyGreater
+ >
+ : detail::envelope::envelope_expand_one<Point, Box>
+{};
+
+
+template
+<
+ typename BoxIn, typename BoxOut,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+ <
+ box_tag, box_tag,
+ BoxIn, BoxOut,
+ StrategyLess, StrategyGreater
+ >
+ : detail::envelope::envelope_expand_one<BoxIn, BoxOut>
+{};
+
+
+template
+<
+ typename Segment, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+ <
+ segment_tag, box_tag,
+ Segment, Box,
+ StrategyLess, StrategyGreater
+ >
+ : detail::envelope::envelope_expand_one<Segment, Box>
+{};
+
+
+template
+<
+ typename Linestring, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+ <
+ linestring_tag, box_tag,
+ Linestring, Box,
+ StrategyLess, StrategyGreater
+ >
+ : detail::envelope::envelope_range<Linestring, Box>
+{};
+
+
+template
+<
+ typename Ring, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+ <
+ ring_tag, box_tag,
+ Ring, Box,
+ StrategyLess, StrategyGreater
+ >
+ : detail::envelope::envelope_range<Ring, Box>
+{};
+
+
+template
+<
+ typename Polygon, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+ <
+ polygon_tag, box_tag,
+ Polygon, Box,
+ StrategyLess, StrategyGreater
+ >
+{
+ static inline void apply(Polygon const& poly, Box& mbr)
+ {
+ // For polygon, inspecting outer ring is sufficient
+
+ detail::envelope::envelope_range
+ <
+ typename ring_type<Polygon>::type,
+ Box
+ >::apply(exterior_ring(poly), mbr);
+ }
+
+};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief \brief_calc{envelope}
+\ingroup envelope
+\details \details_calc{envelope,\det_envelope}.
+\tparam Geometry \tparam_geometry
+\tparam Box \tparam_box
+\param geometry \param_geometry
+\param mbr \param_box \param_set{envelope}
+
+\qbk{[include reference/algorithms/envelope.qbk]}
+\qbk{
+[heading Example]
+[envelope] [envelope_output]
+}
+*/
+template<typename Geometry, typename Box>
+inline void envelope(Geometry const& geometry, Box& mbr)
+{
+ concept::check<Geometry const>();
+ concept::check<Box>();
+
+ dispatch::envelope
+ <
+ typename tag<Geometry>::type, typename tag<Box>::type,
+ Geometry, Box,
+ void, void
+ >::apply(geometry, mbr);
+}
+
+
+/*!
+\brief \brief_calc{envelope}
+\ingroup envelope
+\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
+\tparam Box \tparam_box
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{envelope}
+
+\qbk{[include reference/algorithms/envelope.qbk]}
+\qbk{
+[heading Example]
+[return_envelope] [return_envelope_output]
+}
+*/
+template<typename Box, typename Geometry>
+inline Box return_envelope(Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+ concept::check<Box>();
+
+ Box mbr;
+ dispatch::envelope
+ <
+ typename tag<Geometry>::type, typename tag<Box>::type,
+ Geometry, Box,
+ void, void
+ >::apply(geometry, mbr);
+ return mbr;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
diff --git a/src/boost/geometry/algorithms/equals.hpp b/src/boost/geometry/algorithms/equals.hpp
new file mode 100644
index 0000000..6b094f7
--- /dev/null
+++ b/src/boost/geometry/algorithms/equals.hpp
@@ -0,0 +1,319 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
+
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/mpl/if.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/reverse_dispatch.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/not.hpp>
+
+// For trivial checks
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/length.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace equals
+{
+
+
+template
+<
+ typename Box1,
+ typename Box2,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct box_box
+{
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
+ {
+ if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
+ || !geometry::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
+ {
+ return false;
+ }
+ return box_box<Box1, Box2, Dimension + 1, DimensionCount>::apply(box1, box2);
+ }
+};
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct box_box<Box1, Box2, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Box1 const& , Box2 const& )
+ {
+ return true;
+ }
+};
+
+
+struct area_check
+{
+ template <typename Geometry1, typename Geometry2>
+ static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ {
+ return geometry::math::equals(
+ geometry::area(geometry1),
+ geometry::area(geometry2));
+ }
+};
+
+
+struct length_check
+{
+ template <typename Geometry1, typename Geometry2>
+ static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ {
+ return geometry::math::equals(
+ geometry::length(geometry1),
+ geometry::length(geometry2));
+ }
+};
+
+
+template <typename Geometry1, typename Geometry2, typename TrivialCheck>
+struct equals_by_collection
+{
+ static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+ {
+ if (! TrivialCheck::apply(geometry1, geometry2))
+ {
+ return false;
+ }
+
+ typedef typename geometry::select_most_precise
+ <
+ typename select_coordinate_type
+ <
+ Geometry1, Geometry2
+ >::type,
+ double
+ >::type calculation_type;
+
+ typedef std::vector<collected_vector<calculation_type> > v;
+ v c1, c2;
+
+ geometry::collect_vectors(c1, geometry1);
+ geometry::collect_vectors(c2, geometry2);
+
+ if (boost::size(c1) != boost::size(c2))
+ {
+ return false;
+ }
+
+ std::sort(c1.begin(), c1.end());
+ std::sort(c2.begin(), c2.end());
+
+ // Just check if these vectors are equal.
+ return std::equal(c1.begin(), c1.end(), c2.begin());
+ }
+};
+
+
+}} // namespace detail::equals
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag1, typename Tag2,
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t DimensionCount
+>
+struct equals
+{};
+
+
+template <typename P1, typename P2, std::size_t DimensionCount>
+struct equals<point_tag, point_tag, P1, P2, DimensionCount>
+ : geometry::detail::not_
+ <
+ P1,
+ P2,
+ detail::disjoint::point_point<P1, P2, 0, DimensionCount>
+ >
+{};
+
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct equals<box_tag, box_tag, Box1, Box2, DimensionCount>
+ : detail::equals::box_box<Box1, Box2, 0, DimensionCount>
+{};
+
+
+template <typename Ring1, typename Ring2>
+struct equals<ring_tag, ring_tag, Ring1, Ring2, 2>
+ : detail::equals::equals_by_collection
+ <
+ Ring1, Ring2,
+ detail::equals::area_check
+ >
+{};
+
+
+template <typename Polygon1, typename Polygon2>
+struct equals<polygon_tag, polygon_tag, Polygon1, Polygon2, 2>
+ : detail::equals::equals_by_collection
+ <
+ Polygon1, Polygon2,
+ detail::equals::area_check
+ >
+{};
+
+
+template <typename LineString1, typename LineString2>
+struct equals<linestring_tag, linestring_tag, LineString1, LineString2, 2>
+ : detail::equals::equals_by_collection
+ <
+ LineString1, LineString2,
+ detail::equals::length_check
+ >
+{};
+
+
+template <typename Polygon, typename Ring>
+struct equals<polygon_tag, ring_tag, Polygon, Ring, 2>
+ : detail::equals::equals_by_collection
+ <
+ Polygon, Ring,
+ detail::equals::area_check
+ >
+{};
+
+
+template <typename Ring, typename Box>
+struct equals<ring_tag, box_tag, Ring, Box, 2>
+ : detail::equals::equals_by_collection
+ <
+ Ring, Box,
+ detail::equals::area_check
+ >
+{};
+
+
+template <typename Polygon, typename Box>
+struct equals<polygon_tag, box_tag, Polygon, Box, 2>
+ : detail::equals::equals_by_collection
+ <
+ Polygon, Box,
+ detail::equals::area_check
+ >
+{};
+
+
+template
+<
+ typename Tag1, typename Tag2,
+ typename Geometry1,
+ typename Geometry2,
+ std::size_t DimensionCount
+>
+struct equals_reversed
+{
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ {
+ return equals
+ <
+ Tag2, Tag1,
+ Geometry2, Geometry1,
+ DimensionCount
+ >::apply(g2, g1);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_check{are spatially equal}
+\details \details_check12{equals, is spatially equal}. Spatially equal means
+ that the same point set is included. A box can therefore be spatially equal
+ to a ring or a polygon, or a linestring can be spatially equal to a
+ multi-linestring or a segment. This only theoretically, not all combinations
+ are implemented yet.
+\ingroup equals
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return \return_check2{are spatially equal}
+
+\qbk{[include reference/algorithms/equals.qbk]}
+
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check_concepts_and_equal_dimensions
+ <
+ Geometry1 const,
+ Geometry2 const
+ >();
+
+ return boost::mpl::if_c
+ <
+ reverse_dispatch<Geometry1, Geometry2>::type::value,
+ dispatch::equals_reversed
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ dimension<Geometry1>::type::value
+ >,
+ dispatch::equals
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ dimension<Geometry1>::type::value
+ >
+ >::type::apply(geometry1, geometry2);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
+
diff --git a/src/boost/geometry/algorithms/expand.hpp b/src/boost/geometry/algorithms/expand.hpp
new file mode 100644
index 0000000..da7442b
--- /dev/null
+++ b/src/boost/geometry/algorithms/expand.hpp
@@ -0,0 +1,319 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
+
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace expand
+{
+
+
+template
+<
+ typename Box, typename Point,
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_loop
+{
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, Point, Dimension
+ >::type less_type;
+
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, Point, Dimension
+ >::type greater_type;
+
+ typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
+
+ static inline void apply(Box& box, Point const& source)
+ {
+ less_type less;
+ greater_type greater;
+
+ coordinate_type const coord = get<Dimension>(source);
+
+ if (less(coord, get<min_corner, Dimension>(box)))
+ {
+ set<min_corner, Dimension>(box, coord);
+ }
+
+ if (greater(coord, get<max_corner, Dimension>(box)))
+ {
+ set<max_corner, Dimension>(box, coord);
+ }
+
+ point_loop
+ <
+ Box, Point,
+ StrategyLess, StrategyGreater,
+ Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ typename Box, typename Point,
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t DimensionCount
+>
+struct point_loop
+ <
+ Box, Point,
+ StrategyLess, StrategyGreater,
+ DimensionCount, DimensionCount
+ >
+{
+ static inline void apply(Box&, Point const&) {}
+};
+
+
+template
+<
+ typename Box, typename Geometry,
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Index,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct indexed_loop
+{
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyLess, 1, Box, Dimension
+ >::type less_type;
+
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ StrategyGreater, -1, Box, Dimension
+ >::type greater_type;
+
+ typedef typename select_coordinate_type
+ <
+ Box,
+ Geometry
+ >::type coordinate_type;
+
+
+ static inline void apply(Box& box, Geometry const& source)
+ {
+ less_type less;
+ greater_type greater;
+
+ coordinate_type const coord = get<Index, Dimension>(source);
+
+ if (less(coord, get<min_corner, Dimension>(box)))
+ {
+ set<min_corner, Dimension>(box, coord);
+ }
+
+ if (greater(coord, get<max_corner, Dimension>(box)))
+ {
+ set<max_corner, Dimension>(box, coord);
+ }
+
+ indexed_loop
+ <
+ Box, Geometry,
+ StrategyLess, StrategyGreater,
+ Index, Dimension + 1, DimensionCount
+ >::apply(box, source);
+ }
+};
+
+
+template
+<
+ typename Box, typename Geometry,
+ typename StrategyLess, typename StrategyGreater,
+ std::size_t Index, std::size_t DimensionCount
+>
+struct indexed_loop
+ <
+ Box, Geometry,
+ StrategyLess, StrategyGreater,
+ Index, DimensionCount, DimensionCount
+ >
+{
+ static inline void apply(Box&, Geometry const&) {}
+};
+
+
+
+// Changes a box such that the other box is also contained by the box
+template
+<
+ typename Box, typename Geometry,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand_indexed
+{
+ static inline void apply(Box& box, Geometry const& geometry)
+ {
+ indexed_loop
+ <
+ Box, Geometry,
+ StrategyLess, StrategyGreater,
+ 0, 0, dimension<Geometry>::type::value
+ >::apply(box, geometry);
+
+ indexed_loop
+ <
+ Box, Geometry,
+ StrategyLess, StrategyGreater,
+ 1, 0, dimension<Geometry>::type::value
+ >::apply(box, geometry);
+ }
+};
+
+}} // namespace detail::expand
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag,
+ typename BoxOut, typename Geometry,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand
+{};
+
+
+// Box + point -> new box containing also point
+template
+<
+ typename BoxOut, typename Point,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand<point_tag, BoxOut, Point, StrategyLess, StrategyGreater>
+ : detail::expand::point_loop
+ <
+ BoxOut, Point,
+ StrategyLess, StrategyGreater,
+ 0, dimension<Point>::type::value
+ >
+{};
+
+
+// Box + box -> new box containing two input boxes
+template
+<
+ typename BoxOut, typename BoxIn,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand<box_tag, BoxOut, BoxIn, StrategyLess, StrategyGreater>
+ : detail::expand::expand_indexed
+ <BoxOut, BoxIn, StrategyLess, StrategyGreater>
+{};
+
+template
+<
+ typename Box, typename Segment,
+ typename StrategyLess, typename StrategyGreater
+>
+struct expand<segment_tag, Box, Segment, StrategyLess, StrategyGreater>
+ : detail::expand::expand_indexed
+ <Box, Segment, StrategyLess, StrategyGreater>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/***
+*!
+\brief Expands a box using the extend (envelope) of another geometry (box, point)
+\ingroup expand
+\tparam Box type of the box
+\tparam Geometry of second geometry, to be expanded with the box
+\param box box to expand another geometry with, might be changed
+\param geometry other geometry
+\param strategy_less
+\param strategy_greater
+\note Strategy is currently ignored
+ *
+template
+<
+ typename Box, typename Geometry,
+ typename StrategyLess, typename StrategyGreater
+>
+inline void expand(Box& box, Geometry const& geometry,
+ StrategyLess const& strategy_less,
+ StrategyGreater const& strategy_greater)
+{
+ concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
+
+ dispatch::expand
+ <
+ typename tag<Geometry>::type,
+ Box,
+ Geometry,
+ StrategyLess, StrategyGreater
+ >::apply(box, geometry);
+}
+***/
+
+
+/*!
+\brief Expands a box using the bounding box (envelope) of another geometry (box, point)
+\ingroup expand
+\tparam Box type of the box
+\tparam Geometry \tparam_geometry
+\param box box to be expanded using another geometry, mutable
+\param geometry \param_geometry geometry which envelope (bounding box) will be added to the box
+
+\qbk{[include reference/algorithms/expand.qbk]}
+ */
+template <typename Box, typename Geometry>
+inline void expand(Box& box, Geometry const& geometry)
+{
+ concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
+
+ dispatch::expand
+ <
+ typename tag<Geometry>::type,
+ Box, Geometry,
+ strategy::compare::default_strategy,
+ strategy::compare::default_strategy
+ >::apply(box, geometry);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
diff --git a/src/boost/geometry/algorithms/for_each.hpp b/src/boost/geometry/algorithms/for_each.hpp
new file mode 100644
index 0000000..671f26a
--- /dev/null
+++ b/src/boost/geometry/algorithms/for_each.hpp
@@ -0,0 +1,358 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
+
+
+#include <algorithm>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/geometries/segment.hpp>
+
+#include <boost/geometry/util/add_const_if_c.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each
+{
+
+
+template <typename Point, typename Functor, bool IsConst>
+struct fe_point_per_point
+{
+ static inline Functor apply(
+ typename add_const_if_c<IsConst, Point>::type& point, Functor f)
+ {
+ f(point);
+ return f;
+ }
+};
+
+
+template <typename Point, typename Functor, bool IsConst>
+struct fe_point_per_segment
+{
+ static inline Functor apply(
+ typename add_const_if_c<IsConst, Point>::type& , Functor f)
+ {
+ // TODO: if non-const, we should extract the points from the segment
+ // and call the functor on those two points
+ return f;
+ }
+};
+
+
+template <typename Range, typename Functor, bool IsConst>
+struct fe_range_per_point
+{
+ static inline Functor apply(
+ typename add_const_if_c<IsConst, Range>::type& range,
+ Functor f)
+ {
+ return (std::for_each(boost::begin(range), boost::end(range), f));
+ }
+};
+
+
+template <typename Range, typename Functor, bool IsConst>
+struct fe_range_per_segment
+{
+ static inline Functor apply(
+ typename add_const_if_c<IsConst, Range>::type& range,
+ Functor f)
+ {
+ typedef typename add_const_if_c
+ <
+ IsConst,
+ typename point_type<Range>::type
+ >::type point_type;
+
+ BOOST_AUTO_TPL(it, boost::begin(range));
+ BOOST_AUTO_TPL(previous, it++);
+ while(it != boost::end(range))
+ {
+ model::referring_segment<point_type> s(*previous, *it);
+ f(s);
+ previous = it++;
+ }
+
+ return f;
+ }
+};
+
+
+template <typename Polygon, typename Functor, bool IsConst>
+struct fe_polygon_per_point
+{
+ typedef typename add_const_if_c<IsConst, Polygon>::type poly_type;
+
+ static inline Functor apply(poly_type& poly, Functor f)
+ {
+ typedef fe_range_per_point
+ <
+ typename ring_type<Polygon>::type,
+ Functor,
+ IsConst
+ > per_ring;
+
+ f = per_ring::apply(exterior_ring(poly), f);
+
+ typename interior_return_type<poly_type>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ f = per_ring::apply(*it, f);
+ }
+
+ return f;
+ }
+
+};
+
+
+template <typename Polygon, typename Functor, bool IsConst>
+struct fe_polygon_per_segment
+{
+ typedef typename add_const_if_c<IsConst, Polygon>::type poly_type;
+
+ static inline Functor apply(poly_type& poly, Functor f)
+ {
+ typedef fe_range_per_segment
+ <
+ typename ring_type<Polygon>::type,
+ Functor,
+ IsConst
+ > per_ring;
+
+ f = per_ring::apply(exterior_ring(poly), f);
+
+ typename interior_return_type<poly_type>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ f = per_ring::apply(*it, f);
+ }
+
+ return f;
+ }
+
+};
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename Functor,
+ bool IsConst
+>
+struct for_each_point {};
+
+
+template <typename Point, typename Functor, bool IsConst>
+struct for_each_point<point_tag, Point, Functor, IsConst>
+ : detail::for_each::fe_point_per_point<Point, Functor, IsConst>
+{};
+
+
+template <typename Linestring, typename Functor, bool IsConst>
+struct for_each_point<linestring_tag, Linestring, Functor, IsConst>
+ : detail::for_each::fe_range_per_point<Linestring, Functor, IsConst>
+{};
+
+
+template <typename Ring, typename Functor, bool IsConst>
+struct for_each_point<ring_tag, Ring, Functor, IsConst>
+ : detail::for_each::fe_range_per_point<Ring, Functor, IsConst>
+{};
+
+
+template <typename Polygon, typename Functor, bool IsConst>
+struct for_each_point<polygon_tag, Polygon, Functor, IsConst>
+ : detail::for_each::fe_polygon_per_point<Polygon, Functor, IsConst>
+{};
+
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename Functor,
+ bool IsConst
+>
+struct for_each_segment {};
+
+template <typename Point, typename Functor, bool IsConst>
+struct for_each_segment<point_tag, Point, Functor, IsConst>
+ : detail::for_each::fe_point_per_segment<Point, Functor, IsConst>
+{};
+
+
+template <typename Linestring, typename Functor, bool IsConst>
+struct for_each_segment<linestring_tag, Linestring, Functor, IsConst>
+ : detail::for_each::fe_range_per_segment<Linestring, Functor, IsConst>
+{};
+
+
+template <typename Ring, typename Functor, bool IsConst>
+struct for_each_segment<ring_tag, Ring, Functor, IsConst>
+ : detail::for_each::fe_range_per_segment<Ring, Functor, IsConst>
+{};
+
+
+template <typename Polygon, typename Functor, bool IsConst>
+struct for_each_segment<polygon_tag, Polygon, Functor, IsConst>
+ : detail::for_each::fe_polygon_per_segment<Polygon, Functor, IsConst>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brf_for_each{point}
+\details \det_for_each{point}
+\ingroup for_each
+\param geometry \param_geometry
+\param f \par_for_each_f{const point}
+\tparam Geometry \tparam_geometry
+\tparam Functor \tparam_functor
+
+\qbk{distinguish,const version}
+\qbk{[include reference/algorithms/for_each_point.qbk]}
+\qbk{[heading Example]}
+\qbk{[for_each_point_const] [for_each_point_const_output]}
+*/
+template<typename Geometry, typename Functor>
+inline Functor for_each_point(Geometry const& geometry, Functor f)
+{
+ concept::check<Geometry const>();
+
+ return dispatch::for_each_point
+ <
+ typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
+ Geometry,
+ Functor,
+ true
+ >::apply(geometry, f);
+}
+
+
+/*!
+\brief \brf_for_each{point}
+\details \det_for_each{point}
+\ingroup for_each
+\param geometry \param_geometry
+\param f \par_for_each_f{point}
+\tparam Geometry \tparam_geometry
+\tparam Functor \tparam_functor
+
+\qbk{[include reference/algorithms/for_each_point.qbk]}
+\qbk{[heading Example]}
+\qbk{[for_each_point] [for_each_point_output]}
+*/
+template<typename Geometry, typename Functor>
+inline Functor for_each_point(Geometry& geometry, Functor f)
+{
+ concept::check<Geometry>();
+
+ return dispatch::for_each_point
+ <
+ typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
+ Geometry,
+ Functor,
+ false
+ >::apply(geometry, f);
+}
+
+
+/*!
+\brief \brf_for_each{segment}
+\details \det_for_each{segment}
+\ingroup for_each
+\param geometry \param_geometry
+\param f \par_for_each_f{const segment}
+\tparam Geometry \tparam_geometry
+\tparam Functor \tparam_functor
+
+\qbk{distinguish,const version}
+\qbk{[include reference/algorithms/for_each_segment.qbk]}
+\qbk{[heading Example]}
+\qbk{[for_each_segment_const] [for_each_segment_const_output]}
+*/
+template<typename Geometry, typename Functor>
+inline Functor for_each_segment(Geometry const& geometry, Functor f)
+{
+ concept::check<Geometry const>();
+
+ return dispatch::for_each_segment
+ <
+ typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
+ Geometry,
+ Functor,
+ true
+ >::apply(geometry, f);
+}
+
+
+/*!
+\brief \brf_for_each{segment}
+\details \det_for_each{segment}
+\ingroup for_each
+\param geometry \param_geometry
+\param f \par_for_each_f{segment}
+\tparam Geometry \tparam_geometry
+\tparam Functor \tparam_functor
+
+\qbk{[include reference/algorithms/for_each_segment.qbk]}
+*/
+template<typename Geometry, typename Functor>
+inline Functor for_each_segment(Geometry& geometry, Functor f)
+{
+ concept::check<Geometry>();
+
+ return dispatch::for_each_segment
+ <
+ typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
+ Geometry,
+ Functor,
+ false
+ >::apply(geometry, f);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
diff --git a/src/boost/geometry/algorithms/intersection.hpp b/src/boost/geometry/algorithms/intersection.hpp
new file mode 100644
index 0000000..8d3dd68
--- /dev/null
+++ b/src/boost/geometry/algorithms/intersection.hpp
@@ -0,0 +1,237 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
+
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection
+{
+
+template
+<
+ typename Box1, typename Box2,
+ typename BoxOut,
+ typename Strategy,
+ std::size_t Dimension, std::size_t DimensionCount
+>
+struct intersection_box_box
+{
+ static inline bool apply(Box1 const& box1,
+ Box2 const& box2, BoxOut& box_out,
+ Strategy const& strategy)
+ {
+ typedef typename coordinate_type<BoxOut>::type ct;
+
+ ct min1 = get<min_corner, Dimension>(box1);
+ ct min2 = get<min_corner, Dimension>(box2);
+ ct max1 = get<max_corner, Dimension>(box1);
+ ct max2 = get<max_corner, Dimension>(box2);
+
+ if (max1 < min2 || max2 < min1)
+ {
+ return false;
+ }
+ // Set dimensions of output coordinate
+ set<min_corner, Dimension>(box_out, min1 < min2 ? min2 : min1);
+ set<max_corner, Dimension>(box_out, max1 > max2 ? max2 : max1);
+
+ return intersection_box_box
+ <
+ Box1, Box2, BoxOut, Strategy,
+ Dimension + 1, DimensionCount
+ >::apply(box1, box2, box_out, strategy);
+ }
+};
+
+template
+<
+ typename Box1, typename Box2,
+ typename BoxOut,
+ typename Strategy,
+ std::size_t DimensionCount
+>
+struct intersection_box_box<Box1, Box2, BoxOut, Strategy, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Box1 const&, Box2 const&, BoxOut&, Strategy const&)
+ {
+ return true;
+ }
+};
+
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// By default, all is forwarded to the intersection_insert-dispatcher
+template
+<
+ typename Tag1, typename Tag2, typename TagOut,
+ typename Geometry1, typename Geometry2,
+ typename GeometryOut,
+ typename Strategy
+>
+struct intersection
+{
+ typedef std::back_insert_iterator<GeometryOut> output_iterator;
+
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
+ {
+ typedef typename boost::range_value<GeometryOut>::type OneOut;
+
+ intersection_insert
+ <
+ Tag1, Tag2, typename geometry::tag<OneOut>::type,
+ geometry::is_areal<Geometry1>::value,
+ geometry::is_areal<Geometry2>::value,
+ geometry::is_areal<OneOut>::value,
+ Geometry1, Geometry2,
+ detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, false>::value,
+ detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, false>::value,
+ detail::overlay::do_reverse<geometry::point_order<OneOut>::value>::value,
+ output_iterator, OneOut,
+ overlay_intersection,
+ Strategy
+ >::apply(geometry1, geometry2, std::back_inserter(geometry_out), strategy);
+
+ return true;
+ }
+
+};
+
+
+template
+<
+ typename Box1, typename Box2,
+ typename BoxOut,
+ typename Strategy
+>
+struct intersection
+ <
+ box_tag, box_tag, box_tag,
+ Box1, Box2, BoxOut,
+ Strategy
+ > : public detail::intersection::intersection_box_box
+ <
+ Box1, Box2, BoxOut,
+ Strategy,
+ 0, geometry::dimension<Box1>::value
+ >
+{};
+
+
+template
+<
+ typename Tag1, typename Tag2, typename TagOut,
+ typename Geometry1, typename Geometry2,
+ typename GeometryOut,
+ typename Strategy
+>
+struct intersection_reversed
+{
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& geometry_out,
+ Strategy const& strategy)
+ {
+ return intersection
+ <
+ Tag2, Tag1, TagOut,
+ Geometry2, Geometry1,
+ GeometryOut, Strategy
+ >::apply(geometry2, geometry1, geometry_out, strategy);
+ }
+};
+
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_calc2{intersection}
+\ingroup intersection
+\details \details_calc2{intersection, spatial set theoretic intersection}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
+ the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param geometry_out The output geometry, either a multi_point, multi_polygon,
+ multi_linestring, or a box (for intersection of two boxes)
+
+\qbk{[include reference/algorithms/intersection.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename GeometryOut
+>
+inline bool intersection(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ GeometryOut& geometry_out)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ typedef strategy_intersection
+ <
+ typename cs_tag<Geometry1>::type,
+ Geometry1,
+ Geometry2,
+ typename geometry::point_type<Geometry1>::type
+ > strategy;
+
+
+ return boost::mpl::if_c
+ <
+ geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
+ dispatch::intersection_reversed
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type,
+ typename geometry::tag<GeometryOut>::type,
+ Geometry1, Geometry2, GeometryOut, strategy
+ >,
+ dispatch::intersection
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type,
+ typename geometry::tag<GeometryOut>::type,
+ Geometry1, Geometry2, GeometryOut, strategy
+ >
+ >::type::apply(geometry1, geometry2, geometry_out, strategy());
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
diff --git a/src/boost/geometry/algorithms/intersects.hpp b/src/boost/geometry/algorithms/intersects.hpp
new file mode 100644
index 0000000..f367f2e
--- /dev/null
+++ b/src/boost/geometry/algorithms/intersects.hpp
@@ -0,0 +1,106 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_INTERSECTS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_INTERSECTS_HPP
+
+
+#include <deque>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
+#include <boost/geometry/algorithms/disjoint.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief \brief_check{has at least one intersection (crossing or self-tangency)}
+\note This function can be called for one geometry (self-intersection) and
+ also for two geometries (intersection)
+\ingroup intersects
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_check{is self-intersecting}
+
+\qbk{distinguish,one geometry}
+\qbk{[def __one_parameter__]}
+\qbk{[include reference/algorithms/intersects.qbk]}
+*/
+template <typename Geometry>
+inline bool intersects(Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+
+ typedef detail::overlay::turn_info
+ <
+ typename geometry::point_type<Geometry>::type
+ > turn_info;
+ std::deque<turn_info> turns;
+
+ typedef typename strategy_intersection
+ <
+ typename cs_tag<Geometry>::type,
+ Geometry,
+ Geometry,
+ typename geometry::point_type<Geometry>::type
+ >::segment_intersection_strategy_type segment_intersection_strategy_type;
+
+ typedef detail::overlay::get_turn_info
+ <
+ typename point_type<Geometry>::type,
+ typename point_type<Geometry>::type,
+ turn_info,
+ detail::overlay::assign_null_policy
+ > TurnPolicy;
+
+ detail::disjoint::disjoint_interrupt_policy policy;
+ detail::self_get_turn_points::get_turns
+ <
+ Geometry,
+ std::deque<turn_info>,
+ TurnPolicy,
+ detail::disjoint::disjoint_interrupt_policy
+ >::apply(geometry, turns, policy);
+ return policy.has_intersections;
+}
+
+
+/*!
+\brief \brief_check2{have at least one intersection}
+\ingroup intersects
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return \return_check2{intersect each other}
+
+\qbk{distinguish,two geometries}
+\qbk{[include reference/algorithms/intersects.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool intersects(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ return ! geometry::disjoint(geometry1, geometry2);
+}
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTS_HPP
diff --git a/src/boost/geometry/algorithms/length.hpp b/src/boost/geometry/algorithms/length.hpp
new file mode 100644
index 0000000..de53a39
--- /dev/null
+++ b/src/boost/geometry/algorithms/length.hpp
@@ -0,0 +1,204 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP
+
+#include <iterator>
+
+#include <boost/range.hpp>
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/closure.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/detail/calculate_null.hpp>
+// #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/default_length_result.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace length
+{
+
+
+template<typename Segment, typename Strategy>
+struct segment_length
+{
+ static inline typename default_length_result<Segment>::type apply(
+ Segment const& segment, Strategy const& strategy)
+ {
+ typedef typename point_type<Segment>::type point_type;
+ point_type p1, p2;
+ geometry::detail::assign_point_from_index<0>(segment, p1);
+ geometry::detail::assign_point_from_index<1>(segment, p2);
+ return strategy.apply(p1, p2);
+ }
+};
+
+/*!
+\brief Internal, calculates length of a linestring using iterator pairs and
+ specified strategy
+\note for_each could be used here, now that point_type is changed by boost
+ range iterator
+*/
+template<typename Range, typename Strategy, closure_selector Closure>
+struct range_length
+{
+ typedef typename default_length_result<Range>::type return_type;
+
+ static inline return_type apply(
+ Range const& range, Strategy const& strategy)
+ {
+ typedef typename closeable_view<Range const, Closure>::type view_type;
+ typedef typename boost::range_iterator
+ <
+ view_type const
+ >::type iterator_type;
+
+ return_type sum = return_type();
+ view_type view(range);
+ iterator_type it = boost::begin(view), end = boost::end(view);
+ if(it != end)
+ {
+ for(iterator_type previous = it++;
+ it != end;
+ ++previous, ++it)
+ {
+ // Add point-point distance using the return type belonging
+ // to strategy
+ sum += strategy.apply(*previous, *it);
+ }
+ }
+
+ return sum;
+ }
+};
+
+
+}} // namespace detail::length
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Tag, typename Geometry, typename Strategy>
+struct length : detail::calculate_null
+ <
+ typename default_length_result<Geometry>::type,
+ Geometry,
+ Strategy
+ >
+{};
+
+
+template <typename Geometry, typename Strategy>
+struct length<linestring_tag, Geometry, Strategy>
+ : detail::length::range_length<Geometry, Strategy, closed>
+{};
+
+
+// RING: length is currently 0; it might be argued that it is the "perimeter"
+
+
+template <typename Geometry, typename Strategy>
+struct length<segment_tag, Geometry, Strategy>
+ : detail::length::segment_length<Geometry, Strategy>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_calc{length}
+\ingroup length
+\details \details_calc{length, length (the sum of distances between consecutive points)}. \details_default_strategy
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{length}
+
+\qbk{[include reference/algorithms/length.qbk]}
+\qbk{[length] [length_output]}
+ */
+template<typename Geometry>
+inline typename default_length_result<Geometry>::type length(
+ Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ // detail::throw_on_empty_input(geometry);
+
+ typedef typename strategy::distance::services::default_strategy
+ <
+ point_tag, typename point_type<Geometry>::type
+ >::type strategy_type;
+
+ return dispatch::length
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ strategy_type
+ >::apply(geometry, strategy_type());
+}
+
+
+/*!
+\brief \brief_calc{length} \brief_strategy
+\ingroup length
+\details \details_calc{length, length (the sum of distances between consecutive points)} \brief_strategy. \details_strategy_reasons
+\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{distance}
+\param geometry \param_geometry
+\param strategy \param_strategy{distance}
+\return \return_calc{length}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/length.qbk]}
+\qbk{[length_with_strategy] [length_with_strategy_output]}
+ */
+template<typename Geometry, typename Strategy>
+inline typename default_length_result<Geometry>::type length(
+ Geometry const& geometry, Strategy const& strategy)
+{
+ concept::check<Geometry const>();
+
+ // detail::throw_on_empty_input(geometry);
+
+ return dispatch::length
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Strategy
+ >::apply(geometry, strategy);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP
diff --git a/src/boost/geometry/algorithms/make.hpp b/src/boost/geometry/algorithms/make.hpp
new file mode 100644
index 0000000..d0e3092
--- /dev/null
+++ b/src/boost/geometry/algorithms/make.hpp
@@ -0,0 +1,200 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
+
+#include <boost/geometry/algorithms/assign.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace make
+{
+
+/*!
+\brief Construct a geometry
+\ingroup make
+\tparam Geometry \tparam_geometry
+\tparam Range \tparam_range_point
+\param range \param_range_point
+\return The constructed geometry, here: a linestring or a ring
+
+\qbk{distinguish, with a range}
+\qbk{
+[heading Example]
+[make_with_range] [make_with_range_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.assign.assign_points assign]
+}
+ */
+template <typename Geometry, typename Range>
+inline Geometry make_points(Range const& range)
+{
+ concept::check<Geometry>();
+
+ Geometry geometry;
+ geometry::append(geometry, range);
+ return geometry;
+}
+
+}} // namespace detail::make
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+\brief Construct a geometry
+\ingroup make
+\details
+\note It does not work with array-point types, like int[2]
+\tparam Geometry \tparam_geometry
+\tparam Type \tparam_numeric to specify the coordinates
+\param c1 \param_x
+\param c2 \param_y
+\return The constructed geometry, here: a 2D point
+
+\qbk{distinguish, 2 coordinate values}
+\qbk{
+[heading Example]
+[make_2d_point] [make_2d_point_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.assign.assign_values_3_2_coordinate_values assign]
+}
+*/
+template <typename Geometry, typename Type>
+inline Geometry make(Type const& c1, Type const& c2)
+{
+ concept::check<Geometry>();
+
+ Geometry geometry;
+ dispatch::assign
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ geometry::dimension<Geometry>::type::value
+ >::apply(geometry, c1, c2);
+ return geometry;
+}
+
+/*!
+\brief Construct a geometry
+\ingroup make
+\tparam Geometry \tparam_geometry
+\tparam Type \tparam_numeric to specify the coordinates
+\param c1 \param_x
+\param c2 \param_y
+\param c3 \param_z
+\return The constructed geometry, here: a 3D point
+
+\qbk{distinguish, 3 coordinate values}
+\qbk{
+[heading Example]
+[make_3d_point] [make_3d_point_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.assign.assign_values_4_3_coordinate_values assign]
+}
+ */
+template <typename Geometry, typename Type>
+inline Geometry make(Type const& c1, Type const& c2, Type const& c3)
+{
+ concept::check<Geometry>();
+
+ Geometry geometry;
+ dispatch::assign
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ geometry::dimension<Geometry>::type::value
+ >::apply(geometry, c1, c2, c3);
+ return geometry;
+}
+
+template <typename Geometry, typename Type>
+inline Geometry make(Type const& c1, Type const& c2, Type const& c3, Type const& c4)
+{
+ concept::check<Geometry>();
+
+ Geometry geometry;
+ dispatch::assign
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ geometry::dimension<Geometry>::type::value
+ >::apply(geometry, c1, c2, c3, c4);
+ return geometry;
+}
+
+
+
+
+
+/*!
+\brief Construct a box with inverse infinite coordinates
+\ingroup make
+\details The make_inverse function initializes a 2D or 3D box with large coordinates, the
+ min corner is very large, the max corner is very small. This is useful e.g. in combination
+ with the expand function, to determine the bounding box of a series of geometries.
+\tparam Geometry \tparam_geometry
+\return The constructed geometry, here: a box
+
+\qbk{
+[heading Example]
+[make_inverse] [make_inverse_output]
+
+[heading See also]
+\* [link geometry.reference.algorithms.assign.assign_inverse assign_inverse]
+}
+ */
+template <typename Geometry>
+inline Geometry make_inverse()
+{
+ concept::check<Geometry>();
+
+ Geometry geometry;
+ dispatch::assign_inverse
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(geometry);
+ return geometry;
+}
+
+/*!
+\brief Construct a geometry with its coordinates initialized to zero
+\ingroup make
+\details The make_zero function initializes a 2D or 3D point or box with coordinates of zero
+\tparam Geometry \tparam_geometry
+\return The constructed and zero-initialized geometry
+ */
+template <typename Geometry>
+inline Geometry make_zero()
+{
+ concept::check<Geometry>();
+
+ Geometry geometry;
+ dispatch::assign_zero
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(geometry);
+ return geometry;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
diff --git a/src/boost/geometry/algorithms/not_implemented.hpp b/src/boost/geometry/algorithms/not_implemented.hpp
new file mode 100644
index 0000000..008f111
--- /dev/null
+++ b/src/boost/geometry/algorithms/not_implemented.hpp
@@ -0,0 +1,117 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_NOT_IMPLEMENTED_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_NOT_IMPLEMENTED_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace info
+{
+ struct UNRECOGNIZED_GEOMETRY_TYPE {};
+ struct POINT {};
+ struct LINESTRING {};
+ struct POLYGON {};
+ struct RING {};
+ struct BOX {};
+ struct SEGMENT {};
+ struct MULTI_POINT {};
+ struct MULTI_LINESTRING {};
+ struct MULTI_POLYGON {};
+ struct GEOMETRY_COLLECTION {};
+ template <size_t D> struct DIMENSION {};
+}
+
+
+namespace nyi
+{
+
+
+struct not_implemented_tag {};
+
+template
+<
+ typename Term1,
+ typename Term2,
+ typename Term3
+>
+struct not_implemented_error
+{
+
+#ifndef BOOST_GEOMETRY_IMPLEMENTATION_STATUS_BUILD
+# define BOOST_GEOMETRY_IMPLEMENTATION_STATUS_BUILD false
+#endif
+
+ BOOST_MPL_ASSERT_MSG
+ (
+ BOOST_GEOMETRY_IMPLEMENTATION_STATUS_BUILD,
+ THIS_OPERATION_IS_NOT_OR_NOT_YET_IMPLEMENTED,
+ (
+ types<Term1, Term2, Term3>
+ )
+ );
+};
+
+template <typename Tag>
+struct tag_to_term
+{
+ typedef Tag type;
+};
+
+template <> struct tag_to_term<geometry_not_recognized_tag> { typedef info::UNRECOGNIZED_GEOMETRY_TYPE type; };
+template <> struct tag_to_term<point_tag> { typedef info::POINT type; };
+template <> struct tag_to_term<linestring_tag> { typedef info::LINESTRING type; };
+template <> struct tag_to_term<polygon_tag> { typedef info::POLYGON type; };
+template <> struct tag_to_term<ring_tag> { typedef info::RING type; };
+template <> struct tag_to_term<box_tag> { typedef info::BOX type; };
+template <> struct tag_to_term<segment_tag> { typedef info::SEGMENT type; };
+template <> struct tag_to_term<multi_point_tag> { typedef info::MULTI_POINT type; };
+template <> struct tag_to_term<multi_linestring_tag> { typedef info::MULTI_LINESTRING type; };
+template <> struct tag_to_term<multi_polygon_tag> { typedef info::MULTI_POLYGON type; };
+template <> struct tag_to_term<geometry_collection_tag> { typedef info::GEOMETRY_COLLECTION type; };
+template <int D> struct tag_to_term<mpl::int_<D> > { typedef info::DIMENSION<D> type; };
+
+
+}
+
+
+template
+<
+ typename Term1 = void,
+ typename Term2 = void,
+ typename Term3 = void
+>
+struct not_implemented
+ : nyi::not_implemented_tag,
+ nyi::not_implemented_error
+ <
+ typename mpl::identity<typename nyi::tag_to_term<Term1>::type>::type,
+ typename mpl::identity<typename nyi::tag_to_term<Term2>::type>::type,
+ typename mpl::identity<typename nyi::tag_to_term<Term3>::type>::type
+ >
+{};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_NOT_IMPLEMENTED_HPP
diff --git a/src/boost/geometry/algorithms/num_geometries.hpp b/src/boost/geometry/algorithms/num_geometries.hpp
new file mode 100644
index 0000000..20f35e9
--- /dev/null
+++ b/src/boost/geometry/algorithms/num_geometries.hpp
@@ -0,0 +1,95 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Tag, typename Geometry>
+struct num_geometries
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename Geometry>
+struct num_geometries<single_tag, Geometry>
+{
+ static inline std::size_t apply(Geometry const&)
+ {
+ return 1;
+ }
+};
+
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief \brief_calc{number of geometries}
+\ingroup num_geometries
+\details \details_calc{num_geometries, number of geometries}.
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{number of geometries}
+
+\qbk{[include reference/algorithms/num_geometries.qbk]}
+*/
+template <typename Geometry>
+inline std::size_t num_geometries(Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ return dispatch::num_geometries
+ <
+ typename tag_cast
+ <
+ typename tag<Geometry>::type,
+ single_tag,
+ multi_tag
+ >::type,
+ Geometry
+ >::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_GEOMETRIES_HPP
diff --git a/src/boost/geometry/algorithms/num_interior_rings.hpp b/src/boost/geometry/algorithms/num_interior_rings.hpp
new file mode 100644
index 0000000..2149f46
--- /dev/null
+++ b/src/boost/geometry/algorithms/num_interior_rings.hpp
@@ -0,0 +1,88 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/core/interior_rings.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Tag, typename Geometry>
+struct num_interior_rings
+{
+ static inline std::size_t apply(Geometry const& )
+ {
+ return 0;
+ }
+};
+
+
+
+template <typename Polygon>
+struct num_interior_rings<polygon_tag, Polygon>
+{
+ static inline std::size_t apply(Polygon const& polygon)
+ {
+ return boost::size(geometry::interior_rings(polygon));
+ }
+
+};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief \brief_calc{number of interior rings}
+\ingroup num_interior_rings
+\details \details_calc{num_interior_rings, number of interior rings}.
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{number of interior rings}
+
+\qbk{[include reference/algorithms/num_interior_rings.qbk]}
+
+\note Defined by OGC as "numInteriorRing". To be consistent with "numPoints"
+ letter "s" is appended
+*/
+template <typename Geometry>
+inline std::size_t num_interior_rings(Geometry const& geometry)
+{
+ return dispatch::num_interior_rings
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
diff --git a/src/boost/geometry/algorithms/num_points.hpp b/src/boost/geometry/algorithms/num_points.hpp
new file mode 100644
index 0000000..c480068
--- /dev/null
+++ b/src/boost/geometry/algorithms/num_points.hpp
@@ -0,0 +1,171 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_NUM_POINTS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_NUM_POINTS_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace num_points
+{
+
+
+template <typename Range>
+struct range_count
+{
+ static inline std::size_t apply(Range const& range, bool add_for_open)
+ {
+ std::size_t n = boost::size(range);
+ if (add_for_open && n > 0)
+ {
+ closure_selector const s = geometry::closure<Range>::value;
+
+ if (s == open)
+ {
+ if (geometry::disjoint(*boost::begin(range), *(boost::begin(range) + n - 1)))
+ {
+ return n + 1;
+ }
+ }
+ }
+ return n;
+ }
+};
+
+template <typename Geometry, std::size_t D>
+struct other_count
+{
+ static inline std::size_t apply(Geometry const&, bool)
+ {
+ return D;
+ }
+};
+
+template <typename Polygon>
+struct polygon_count
+{
+ static inline std::size_t apply(Polygon const& poly, bool add_for_open)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ std::size_t n = range_count<ring_type>::apply(
+ exterior_ring(poly), add_for_open);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ n += range_count<ring_type>::apply(*it, add_for_open);
+ }
+
+ return n;
+ }
+};
+
+}} // namespace detail::num_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename Geometry>
+struct num_points
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+template <typename Geometry>
+struct num_points<point_tag, Geometry>
+ : detail::num_points::other_count<Geometry, 1>
+{};
+
+template <typename Geometry>
+struct num_points<box_tag, Geometry>
+ : detail::num_points::other_count<Geometry, 4>
+{};
+
+template <typename Geometry>
+struct num_points<segment_tag, Geometry>
+ : detail::num_points::other_count<Geometry, 2>
+{};
+
+template <typename Geometry>
+struct num_points<linestring_tag, Geometry>
+ : detail::num_points::range_count<Geometry>
+{};
+
+template <typename Geometry>
+struct num_points<ring_tag, Geometry>
+ : detail::num_points::range_count<Geometry>
+{};
+
+template <typename Geometry>
+struct num_points<polygon_tag, Geometry>
+ : detail::num_points::polygon_count<Geometry>
+{};
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief \brief_calc{number of points}
+\ingroup num_points
+\details \details_calc{num_points, number of points}.
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\param add_for_open add one for open geometries (i.e. polygon types which are not closed)
+\return \return_calc{number of points}
+
+\qbk{[include reference/algorithms/num_points.qbk]}
+*/
+template <typename Geometry>
+inline std::size_t num_points(Geometry const& geometry, bool add_for_open = false)
+{
+ concept::check<Geometry const>();
+
+ return dispatch::num_points
+ <
+ typename tag_cast<typename tag<Geometry>::type, multi_tag>::type,
+ Geometry
+ >::apply(geometry, add_for_open);
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_NUM_POINTS_HPP
diff --git a/src/boost/geometry/algorithms/overlaps.hpp b/src/boost/geometry/algorithms/overlaps.hpp
new file mode 100644
index 0000000..2f854b4
--- /dev/null
+++ b/src/boost/geometry/algorithms/overlaps.hpp
@@ -0,0 +1,202 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
+
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+
+#include <boost/geometry/core/access.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlaps
+{
+
+template
+<
+ typename Box1,
+ typename Box2,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct box_box_loop
+{
+ static inline void apply(Box1 const& b1, Box2 const& b2,
+ bool& overlaps, bool& one_in_two, bool& two_in_one)
+ {
+ assert_dimension_equal<Box1, Box2>();
+
+ typedef typename coordinate_type<Box1>::type coordinate_type1;
+ typedef typename coordinate_type<Box2>::type coordinate_type2;
+
+ coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
+ coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
+ coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
+ coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
+
+ // We might use the (not yet accepted) Boost.Interval
+ // submission in the future
+
+ // If:
+ // B1: |-------|
+ // B2: |------|
+ // in any dimension -> no overlap
+ if (max1 <= min2 || min1 >= max2)
+ {
+ overlaps = false;
+ return;
+ }
+
+ // If:
+ // B1: |--------------------|
+ // B2: |-------------|
+ // in all dimensions -> within, then no overlap
+ // B1: |--------------------|
+ // B2: |-------------|
+ // this is "within-touch" -> then no overlap. So use < and >
+ if (min1 < min2 || max1 > max2)
+ {
+ one_in_two = false;
+ }
+ // Same other way round
+ if (min2 < min1 || max2 > max1)
+ {
+ two_in_one = false;
+ }
+
+ box_box_loop
+ <
+ Box1,
+ Box2,
+ Dimension + 1,
+ DimensionCount
+ >::apply(b1, b2, overlaps, one_in_two, two_in_one);
+ }
+};
+
+template
+<
+ typename Box1,
+ typename Box2,
+ std::size_t DimensionCount
+>
+struct box_box_loop<Box1, Box2, DimensionCount, DimensionCount>
+{
+ static inline void apply(Box1 const& , Box2 const&, bool&, bool&, bool&)
+ {
+ }
+};
+
+template
+<
+ typename Box1,
+ typename Box2
+>
+struct box_box
+{
+ static inline bool apply(Box1 const& b1, Box2 const& b2)
+ {
+ bool overlaps = true;
+ bool within1 = true;
+ bool within2 = true;
+ box_box_loop
+ <
+ Box1,
+ Box2,
+ 0,
+ dimension<Box1>::type::value
+ >::apply(b1, b2, overlaps, within1, within2);
+
+ /*
+ \see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
+ where is stated that "inside" is not an "overlap",
+ this is true and is implemented as such.
+ */
+ return overlaps && ! within1 && ! within2;
+ }
+};
+
+
+
+}} // namespace detail::overlaps
+#endif // DOXYGEN_NO_DETAIL
+
+//struct not_implemented_for_this_geometry_type : public boost::false_type {};
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag1,
+ typename Tag2,
+ typename Geometry1,
+ typename Geometry2
+>
+struct overlaps
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry1, Geometry2>)
+ );
+};
+
+
+template <typename Box1, typename Box2>
+struct overlaps<box_tag, box_tag, Box1, Box2>
+ : detail::overlaps::box_box<Box1, Box2>
+{};
+
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_check2{overlap}
+\ingroup overlaps
+\return \return_check2{overlap}
+
+\qbk{[include reference/algorithms/overlaps.qbk]}
+*/
+template <typename Geometry1, typename Geometry2>
+inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ return dispatch::overlaps
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
diff --git a/src/boost/geometry/algorithms/perimeter.hpp b/src/boost/geometry/algorithms/perimeter.hpp
new file mode 100644
index 0000000..adeb0b0
--- /dev/null
+++ b/src/boost/geometry/algorithms/perimeter.hpp
@@ -0,0 +1,144 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
+
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/default_length_result.hpp>
+#include <boost/geometry/algorithms/length.hpp>
+#include <boost/geometry/algorithms/detail/calculate_null.hpp>
+#include <boost/geometry/algorithms/detail/calculate_sum.hpp>
+// #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// Default perimeter is 0.0, specializations implement calculated values
+template <typename Tag, typename Geometry, typename Strategy>
+struct perimeter : detail::calculate_null
+ <
+ typename default_length_result<Geometry>::type,
+ Geometry,
+ Strategy
+ >
+{};
+
+template <typename Geometry, typename Strategy>
+struct perimeter<ring_tag, Geometry, Strategy>
+ : detail::length::range_length
+ <
+ Geometry,
+ Strategy,
+ closure<Geometry>::value
+ >
+{};
+
+template <typename Polygon, typename Strategy>
+struct perimeter<polygon_tag, Polygon, Strategy>
+ : detail::calculate_polygon_sum
+ <
+ typename default_length_result<Polygon>::type,
+ Polygon,
+ Strategy,
+ detail::length::range_length
+ <
+ typename ring_type<Polygon>::type,
+ Strategy,
+ closure<Polygon>::value
+ >
+ >
+{};
+
+
+// box,n-sphere: to be implemented
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_calc{perimeter}
+\ingroup perimeter
+\details The function perimeter returns the perimeter of a geometry,
+ using the default distance-calculation-strategy
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_calc{perimeter}
+
+\qbk{[include reference/algorithms/perimeter.qbk]}
+ */
+template<typename Geometry>
+inline typename default_length_result<Geometry>::type perimeter(
+ Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename strategy::distance::services::default_strategy
+ <
+ point_tag, point_type
+ >::type strategy_type;
+
+ // detail::throw_on_empty_input(geometry);
+
+ return dispatch::perimeter
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ strategy_type
+ >::apply(geometry, strategy_type());
+}
+
+/*!
+\brief \brief_calc{perimeter} \brief_strategy
+\ingroup perimeter
+\details The function perimeter returns the perimeter of a geometry,
+ using specified strategy
+\tparam Geometry \tparam_geometry
+\tparam Strategy \tparam_strategy{distance}
+\param geometry \param_geometry
+\param strategy strategy to be used for distance calculations.
+\return \return_calc{perimeter}
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/perimeter.qbk]}
+ */
+template<typename Geometry, typename Strategy>
+inline typename default_length_result<Geometry>::type perimeter(
+ Geometry const& geometry, Strategy const& strategy)
+{
+ concept::check<Geometry const>();
+
+ // detail::throw_on_empty_input(geometry);
+
+ return dispatch::perimeter
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Strategy
+ >::apply(geometry, strategy);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP
+
diff --git a/src/boost/geometry/algorithms/reverse.hpp b/src/boost/geometry/algorithms/reverse.hpp
new file mode 100644
index 0000000..bf0ef2d
--- /dev/null
+++ b/src/boost/geometry/algorithms/reverse.hpp
@@ -0,0 +1,134 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
+
+#include <algorithm>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace reverse
+{
+
+
+template <typename Range>
+struct range_reverse
+{
+ static inline void apply(Range& range)
+ {
+ std::reverse(boost::begin(range), boost::end(range));
+ }
+};
+
+
+template <typename Polygon>
+struct polygon_reverse
+{
+ static inline void apply(Polygon& polygon)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ typedef range_reverse<ring_type> per_range;
+ per_range::apply(exterior_ring(polygon));
+
+ typename interior_return_type<Polygon>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ per_range::apply(*it);
+ }
+ }
+};
+
+
+}} // namespace detail::reverse
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename Geometry
+>
+struct reverse
+{
+ static inline void apply(Geometry&)
+ {}
+};
+
+
+template <typename Ring>
+struct reverse<ring_tag, Ring>
+ : detail::reverse::range_reverse<Ring>
+{};
+
+
+template <typename LineString>
+struct reverse<linestring_tag, LineString>
+ : detail::reverse::range_reverse<LineString>
+{};
+
+
+template <typename Polygon>
+struct reverse<polygon_tag, Polygon>
+ : detail::reverse::polygon_reverse<Polygon>
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief Reverses the points within a geometry
+\details Generic function to reverse a geometry. It resembles the std::reverse
+ functionality, but it takes the geometry type into account. Only for a ring
+ or for a linestring it is the same as the std::reverse.
+\ingroup reverse
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry which will be reversed
+
+\qbk{[include reference/algorithms/reverse.qbk]}
+*/
+template <typename Geometry>
+inline void reverse(Geometry& geometry)
+{
+ concept::check<Geometry>();
+
+ dispatch::reverse
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(geometry);
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_REVERSE_HPP
diff --git a/src/boost/geometry/algorithms/simplify.hpp b/src/boost/geometry/algorithms/simplify.hpp
new file mode 100644
index 0000000..225321d
--- /dev/null
+++ b/src/boost/geometry/algorithms/simplify.hpp
@@ -0,0 +1,405 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
+
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
+#include <boost/geometry/strategies/concepts/simplify_concept.hpp>
+
+#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace simplify
+{
+
+template<typename Range, typename Strategy>
+struct simplify_range_insert
+{
+ template <typename OutputIterator, typename Distance>
+ static inline void apply(Range const& range, OutputIterator out,
+ Distance const& max_distance, Strategy const& strategy)
+ {
+ if (boost::size(range) <= 2 || max_distance < 0)
+ {
+ std::copy(boost::begin(range), boost::end(range), out);
+ }
+ else
+ {
+ strategy.apply(range, out, max_distance);
+ }
+ }
+};
+
+
+template<typename Range, typename Strategy>
+struct simplify_copy
+{
+ template <typename Distance>
+ static inline void apply(Range const& range, Range& out,
+ Distance const& , Strategy const& )
+ {
+ std::copy
+ (
+ boost::begin(range), boost::end(range), std::back_inserter(out)
+ );
+ }
+};
+
+
+template<typename Range, typename Strategy, std::size_t Minimum>
+struct simplify_range
+{
+ template <typename Distance>
+ static inline void apply(Range const& range, Range& out,
+ Distance const& max_distance, Strategy const& strategy)
+ {
+ // Call do_container for a linestring / ring
+
+ /* For a RING:
+ The first/last point (the closing point of the ring) should maybe
+ be excluded because it lies on a line with second/one but last.
+ Here it is never excluded.
+
+ Note also that, especially if max_distance is too large,
+ the output ring might be self intersecting while the input ring is
+ not, although chances are low in normal polygons
+
+ Finally the inputring might have 3 (open) or 4 (closed) points (=correct),
+ the output < 3 or 4(=wrong)
+ */
+
+ if (boost::size(range) <= int(Minimum) || max_distance < 0.0)
+ {
+ simplify_copy<Range, Strategy>::apply
+ (
+ range, out, max_distance, strategy
+ );
+ }
+ else
+ {
+ simplify_range_insert<Range, Strategy>::apply
+ (
+ range, std::back_inserter(out), max_distance, strategy
+ );
+ }
+ }
+};
+
+template<typename Polygon, typename Strategy>
+struct simplify_polygon
+{
+ template <typename Distance>
+ static inline void apply(Polygon const& poly_in, Polygon& poly_out,
+ Distance const& max_distance, Strategy const& strategy)
+ {
+ typedef typename ring_type<Polygon>::type ring_type;
+
+ int const Minimum = core_detail::closure::minimum_ring_size
+ <
+ geometry::closure<Polygon>::value
+ >::value;
+
+ // Note that if there are inner rings, and distance is too large,
+ // they might intersect with the outer ring in the output,
+ // while it didn't in the input.
+ simplify_range<ring_type, Strategy, Minimum>::apply(exterior_ring(poly_in),
+ exterior_ring(poly_out),
+ max_distance, strategy);
+
+ traits::resize
+ <
+ typename boost::remove_reference
+ <
+ typename traits::interior_mutable_type<Polygon>::type
+ >::type
+ >::apply(interior_rings(poly_out), num_interior_rings(poly_in));
+
+ typename interior_return_type<Polygon const>::type rings_in
+ = interior_rings(poly_in);
+ typename interior_return_type<Polygon>::type rings_out
+ = interior_rings(poly_out);
+ BOOST_AUTO_TPL(it_out, boost::begin(rings_out));
+ for (BOOST_AUTO_TPL(it_in, boost::begin(rings_in));
+ it_in != boost::end(rings_in);
+ ++it_in, ++it_out)
+ {
+ simplify_range<ring_type, Strategy, Minimum>::apply(*it_in,
+ *it_out, max_distance, strategy);
+ }
+ }
+};
+
+
+}} // namespace detail::simplify
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry, typename Strategy>
+struct simplify
+{
+};
+
+template <typename Point, typename Strategy>
+struct simplify<point_tag, Point, Strategy>
+{
+ template <typename Distance>
+ static inline void apply(Point const& point, Point& out,
+ Distance const& , Strategy const& )
+ {
+ geometry::convert(point, out);
+ }
+};
+
+
+template <typename Linestring, typename Strategy>
+struct simplify<linestring_tag, Linestring, Strategy>
+ : detail::simplify::simplify_range
+ <
+ Linestring,
+ Strategy,
+ 2
+ >
+{};
+
+template <typename Ring, typename Strategy>
+struct simplify<ring_tag, Ring, Strategy>
+ : detail::simplify::simplify_range
+ <
+ Ring,
+ Strategy,
+ core_detail::closure::minimum_ring_size
+ <
+ geometry::closure<Ring>::value
+ >::value
+ >
+{};
+
+template <typename Polygon, typename Strategy>
+struct simplify<polygon_tag, Polygon, Strategy>
+ : detail::simplify::simplify_polygon
+ <
+ Polygon,
+ Strategy
+ >
+{};
+
+
+template <typename Tag, typename Geometry, typename Strategy>
+struct simplify_insert
+{
+};
+
+
+template <typename Linestring, typename Strategy>
+struct simplify_insert<linestring_tag, Linestring, Strategy>
+ : detail::simplify::simplify_range_insert
+ <
+ Linestring,
+ Strategy
+ >
+{};
+
+template <typename Ring, typename Strategy>
+struct simplify_insert<ring_tag, Ring, Strategy>
+ : detail::simplify::simplify_range_insert
+ <
+ Ring,
+ Strategy
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Simplify a geometry using a specified strategy
+\ingroup simplify
+\tparam Geometry \tparam_geometry
+\tparam Distance A numerical distance measure
+\tparam Strategy A type fulfilling a SimplifyStrategy concept
+\param strategy A strategy to calculate simplification
+\param geometry input geometry, to be simplified
+\param out output geometry, simplified version of the input geometry
+\param max_distance distance (in units of input coordinates) of a vertex
+ to other segments to be removed
+\param strategy simplify strategy to be used for simplification, might
+ include point-distance strategy
+
+\image html svg_simplify_country.png "The image below presents the simplified country"
+\qbk{distinguish,with strategy}
+*/
+template<typename Geometry, typename Distance, typename Strategy>
+inline void simplify(Geometry const& geometry, Geometry& out,
+ Distance const& max_distance, Strategy const& strategy)
+{
+ concept::check<Geometry>();
+
+ BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy<Strategy>) );
+
+ geometry::clear(out);
+
+ dispatch::simplify
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Strategy
+ >::apply(geometry, out, max_distance, strategy);
+}
+
+
+
+
+/*!
+\brief Simplify a geometry
+\ingroup simplify
+\tparam Geometry \tparam_geometry
+\tparam Distance \tparam_numeric
+\note This version of simplify simplifies a geometry using the default
+ strategy (Douglas Peucker),
+\param geometry input geometry, to be simplified
+\param out output geometry, simplified version of the input geometry
+\param max_distance distance (in units of input coordinates) of a vertex
+ to other segments to be removed
+
+\qbk{[include reference/algorithms/simplify.qbk]}
+ */
+template<typename Geometry, typename Distance>
+inline void simplify(Geometry const& geometry, Geometry& out,
+ Distance const& max_distance)
+{
+ concept::check<Geometry>();
+
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename strategy::distance::services::default_strategy
+ <
+ segment_tag, point_type
+ >::type ds_strategy_type;
+
+ typedef strategy::simplify::douglas_peucker
+ <
+ point_type, ds_strategy_type
+ > strategy_type;
+
+ simplify(geometry, out, max_distance, strategy_type());
+}
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace simplify
+{
+
+
+/*!
+\brief Simplify a geometry, using an output iterator
+ and a specified strategy
+\ingroup simplify
+\tparam Geometry \tparam_geometry
+\param geometry input geometry, to be simplified
+\param out output iterator, outputs all simplified points
+\param max_distance distance (in units of input coordinates) of a vertex
+ to other segments to be removed
+\param strategy simplify strategy to be used for simplification,
+ might include point-distance strategy
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/simplify.qbk]}
+*/
+template<typename Geometry, typename OutputIterator, typename Distance, typename Strategy>
+inline void simplify_insert(Geometry const& geometry, OutputIterator out,
+ Distance const& max_distance, Strategy const& strategy)
+{
+ concept::check<Geometry const>();
+ BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy<Strategy>) );
+
+ dispatch::simplify_insert
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Strategy
+ >::apply(geometry, out, max_distance, strategy);
+}
+
+/*!
+\brief Simplify a geometry, using an output iterator
+\ingroup simplify
+\tparam Geometry \tparam_geometry
+\param geometry input geometry, to be simplified
+\param out output iterator, outputs all simplified points
+\param max_distance distance (in units of input coordinates) of a vertex
+ to other segments to be removed
+
+\qbk{[include reference/algorithms/simplify_insert.qbk]}
+ */
+template<typename Geometry, typename OutputIterator, typename Distance>
+inline void simplify_insert(Geometry const& geometry, OutputIterator out,
+ Distance const& max_distance)
+{
+ typedef typename point_type<Geometry>::type point_type;
+
+ // Concept: output point type = point type of input geometry
+ concept::check<Geometry const>();
+ concept::check<point_type>();
+
+ typedef typename strategy::distance::services::default_strategy
+ <
+ segment_tag, point_type
+ >::type ds_strategy_type;
+
+ typedef strategy::simplify::douglas_peucker
+ <
+ point_type, ds_strategy_type
+ > strategy_type;
+
+ dispatch::simplify_insert
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ strategy_type
+ >::apply(geometry, out, max_distance, strategy_type());
+}
+
+}} // namespace detail::simplify
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
diff --git a/src/boost/geometry/algorithms/sym_difference.hpp b/src/boost/geometry/algorithms/sym_difference.hpp
new file mode 100644
index 0000000..6394576
--- /dev/null
+++ b/src/boost/geometry/algorithms/sym_difference.hpp
@@ -0,0 +1,177 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
+
+#include <algorithm>
+
+
+#include <boost/geometry/algorithms/intersection.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sym_difference
+{
+
+
+
+/*!
+\brief \brief_calc2{symmetric difference} \brief_strategy
+\ingroup sym_difference
+\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
+ \brief_strategy. \details_insert{sym_difference}
+\tparam GeometryOut output geometry type, must be specified
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Strategy \tparam_strategy_overlay
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param out \param_out{difference}
+\param strategy \param_strategy{difference}
+\return \return_out
+
+\qbk{distinguish,with strategy}
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator,
+ typename Strategy
+>
+inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2, OutputIterator out,
+ Strategy const& strategy)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ concept::check<GeometryOut>();
+
+ out = geometry::dispatch::intersection_insert
+ <
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<Geometry2>::type,
+ typename geometry::tag<GeometryOut>::type,
+ geometry::is_areal<Geometry1>::value,
+ geometry::is_areal<Geometry2>::value,
+ geometry::is_areal<GeometryOut>::value,
+ Geometry1, Geometry2,
+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value,
+ geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
+ OutputIterator, GeometryOut,
+ overlay_difference,
+ Strategy
+ >::apply(geometry1, geometry2, out, strategy);
+ out = geometry::dispatch::intersection_insert
+ <
+ typename geometry::tag<Geometry2>::type,
+ typename geometry::tag<Geometry1>::type,
+ typename geometry::tag<GeometryOut>::type,
+ geometry::is_areal<Geometry2>::value,
+ geometry::is_areal<Geometry1>::value,
+ geometry::is_areal<GeometryOut>::value,
+ Geometry2, Geometry1,
+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
+ geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, true>::value,
+ geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
+ OutputIterator, GeometryOut,
+ overlay_difference,
+ Strategy
+ >::apply(geometry2, geometry1, out, strategy);
+ return out;
+}
+
+
+/*!
+\brief \brief_calc2{symmetric difference}
+\ingroup sym_difference
+\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
+ \details_insert{sym_difference}
+\tparam GeometryOut output geometry type, must be specified
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param out \param_out{difference}
+\return \return_out
+
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator
+>
+inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2, OutputIterator out)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ concept::check<GeometryOut>();
+
+ typedef strategy_intersection
+ <
+ typename cs_tag<GeometryOut>::type,
+ Geometry1,
+ Geometry2,
+ typename geometry::point_type<GeometryOut>::type
+ > strategy_type;
+
+ return sym_difference_insert<GeometryOut>(geometry1, geometry2, out, strategy_type());
+}
+
+}} // namespace detail::sym_difference
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief \brief_calc2{symmetric difference}
+\ingroup sym_difference
+\details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Collection output collection, either a multi-geometry,
+ or a std::vector<Geometry> / std::deque<Geometry> etc
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param output_collection the output collection
+
+\qbk{[include reference/algorithms/sym_difference.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Collection
+>
+inline void sym_difference(Geometry1 const& geometry1,
+ Geometry2 const& geometry2, Collection& output_collection)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ typedef typename boost::range_value<Collection>::type geometry_out;
+ concept::check<geometry_out>();
+
+ detail::sym_difference::sym_difference_insert<geometry_out>(
+ geometry1, geometry2,
+ std::back_inserter(output_collection));
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
diff --git a/src/boost/geometry/algorithms/touches.hpp b/src/boost/geometry/algorithms/touches.hpp
new file mode 100644
index 0000000..7d424af
--- /dev/null
+++ b/src/boost/geometry/algorithms/touches.hpp
@@ -0,0 +1,181 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
+
+
+#include <deque>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/num_geometries.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace touches
+{
+
+template <typename Turn>
+inline bool ok_for_touch(Turn const& turn)
+{
+ return turn.both(detail::overlay::operation_union)
+ || turn.both(detail::overlay::operation_blocked)
+ || turn.combination(detail::overlay::operation_union, detail::overlay::operation_blocked)
+ ;
+}
+
+template <typename Turns>
+inline bool has_only_turns(Turns const& turns)
+{
+ bool has_touch = false;
+ typedef typename boost::range_iterator<Turns const>::type iterator_type;
+ for (iterator_type it = boost::begin(turns); it != boost::end(turns); ++it)
+ {
+ if (it->has(detail::overlay::operation_intersection))
+ {
+ return false;
+ }
+
+ switch(it->method)
+ {
+ case detail::overlay::method_crosses:
+ return false;
+ case detail::overlay::method_equal:
+ // Segment spatially equal means: at the right side
+ // the polygon internally overlaps. So return false.
+ return false;
+ case detail::overlay::method_touch:
+ case detail::overlay::method_touch_interior:
+ case detail::overlay::method_collinear:
+ if (ok_for_touch(*it))
+ {
+ has_touch = true;
+ }
+ else
+ {
+ return false;
+ }
+ break;
+ case detail::overlay::method_none :
+ case detail::overlay::method_disjoint :
+ case detail::overlay::method_error :
+ break;
+ }
+ }
+ return has_touch;
+}
+
+}}
+
+/*!
+\brief \brief_check{has at least one touching point (self-tangency)}
+\note This function can be called for one geometry (self-tangency) and
+ also for two geometries (touch)
+\ingroup touches
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry
+\return \return_check{is self-touching}
+
+\qbk{distinguish,one geometry}
+\qbk{[def __one_parameter__]}
+\qbk{[include reference/algorithms/touches.qbk]}
+*/
+template <typename Geometry>
+inline bool touches(Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ typedef detail::overlay::turn_info
+ <
+ typename geometry::point_type<Geometry>::type
+ > turn_info;
+
+ typedef detail::overlay::get_turn_info
+ <
+ typename point_type<Geometry>::type,
+ typename point_type<Geometry>::type,
+ turn_info,
+ detail::overlay::assign_null_policy
+ > policy_type;
+
+ std::deque<turn_info> turns;
+ detail::self_get_turn_points::no_interrupt_policy policy;
+ detail::self_get_turn_points::get_turns
+ <
+ Geometry,
+ std::deque<turn_info>,
+ policy_type,
+ detail::self_get_turn_points::no_interrupt_policy
+ >::apply(geometry, turns, policy);
+
+ return detail::touches::has_only_turns(turns);
+}
+
+
+/*!
+\brief \brief_check2{have at least one touching point (tangent - non overlapping)}
+\ingroup touches
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return \return_check2{touch each other}
+
+\qbk{distinguish,two geometries}
+\qbk{[include reference/algorithms/touches.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+
+ typedef detail::overlay::turn_info
+ <
+ typename geometry::point_type<Geometry1>::type
+ > turn_info;
+
+ typedef detail::overlay::get_turn_info
+ <
+ typename point_type<Geometry1>::type,
+ typename point_type<Geometry2>::type,
+ turn_info,
+ detail::overlay::assign_null_policy
+ > policy_type;
+
+ std::deque<turn_info> turns;
+ detail::get_turns::no_interrupt_policy policy;
+ boost::geometry::get_turns
+ <
+ false, false,
+ detail::overlay::assign_null_policy
+ >(geometry1, geometry2, turns, policy);
+
+ return detail::touches::has_only_turns(turns)
+ && ! geometry::detail::disjoint::rings_containing(geometry1, geometry2)
+ && ! geometry::detail::disjoint::rings_containing(geometry2, geometry1)
+ ;
+}
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
diff --git a/src/boost/geometry/algorithms/transform.hpp b/src/boost/geometry/algorithms/transform.hpp
new file mode 100644
index 0000000..22b45dc
--- /dev/null
+++ b/src/boost/geometry/algorithms/transform.hpp
@@ -0,0 +1,351 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_TRANSFORM_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_TRANSFORM_HPP
+
+#include <cmath>
+#include <iterator>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/transform.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace transform
+{
+
+template <typename Point1, typename Point2, typename Strategy>
+struct transform_point
+{
+ static inline bool apply(Point1 const& p1, Point2& p2,
+ Strategy const& strategy)
+ {
+ return strategy.apply(p1, p2);
+ }
+};
+
+
+template <typename Box1, typename Box2, typename Strategy>
+struct transform_box
+{
+ static inline bool apply(Box1 const& b1, Box2& b2,
+ Strategy const& strategy)
+ {
+ typedef typename point_type<Box1>::type point_type1;
+ typedef typename point_type<Box2>::type point_type2;
+
+ point_type1 lower_left, upper_right;
+ detail::assign::assign_box_2d_corner<min_corner, min_corner>(
+ b1, lower_left);
+ detail::assign::assign_box_2d_corner<max_corner, max_corner>(
+ b1, upper_right);
+
+ point_type2 p1, p2;
+ if (strategy.apply(lower_left, p1) && strategy.apply(upper_right, p2))
+ {
+ // Create a valid box and therefore swap if necessary
+ typedef typename coordinate_type<point_type2>::type coordinate_type;
+ coordinate_type x1 = geometry::get<0>(p1)
+ , y1 = geometry::get<1>(p1)
+ , x2 = geometry::get<0>(p2)
+ , y2 = geometry::get<1>(p2);
+
+ if (x1 > x2) { std::swap(x1, x2); }
+ if (y1 > y2) { std::swap(y1, y2); }
+
+ set<min_corner, 0>(b2, x1);
+ set<min_corner, 1>(b2, y1);
+ set<max_corner, 0>(b2, x2);
+ set<max_corner, 1>(b2, y2);
+
+ return true;
+ }
+ return false;
+ }
+};
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+struct transform_box_or_segment
+{
+ static inline bool apply(Geometry1 const& source, Geometry2& target,
+ Strategy const& strategy)
+ {
+ typedef typename point_type<Geometry1>::type point_type1;
+ typedef typename point_type<Geometry2>::type point_type2;
+
+ point_type1 source_point[2];
+ geometry::detail::assign_point_from_index<0>(source, source_point[0]);
+ geometry::detail::assign_point_from_index<1>(source, source_point[1]);
+
+ point_type2 target_point[2];
+ if (strategy.apply(source_point[0], target_point[0])
+ && strategy.apply(source_point[1], target_point[1]))
+ {
+ geometry::detail::assign_point_to_index<0>(target_point[0], target);
+ geometry::detail::assign_point_to_index<1>(target_point[1], target);
+ return true;
+ }
+ return false;
+ }
+};
+
+
+template
+<
+ typename PointOut,
+ typename OutputIterator,
+ typename Range,
+ typename Strategy
+>
+inline bool transform_range_out(Range const& range,
+ OutputIterator out, Strategy const& strategy)
+{
+ PointOut point_out;
+ for(typename boost::range_iterator<Range const>::type
+ it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ if (! transform_point
+ <
+ typename point_type<Range>::type,
+ PointOut,
+ Strategy
+ >::apply(*it, point_out, strategy))
+ {
+ return false;
+ }
+ *out++ = point_out;
+ }
+ return true;
+}
+
+
+template <typename Polygon1, typename Polygon2, typename Strategy>
+struct transform_polygon
+{
+ static inline bool apply(Polygon1 const& poly1, Polygon2& poly2,
+ Strategy const& strategy)
+ {
+ typedef typename ring_type<Polygon1>::type ring1_type;
+ typedef typename ring_type<Polygon2>::type ring2_type;
+ typedef typename point_type<Polygon2>::type point2_type;
+
+ geometry::clear(poly2);
+
+ if (!transform_range_out<point2_type>(exterior_ring(poly1),
+ std::back_inserter(exterior_ring(poly2)), strategy))
+ {
+ return false;
+ }
+
+ // Note: here a resizeable container is assumed.
+ traits::resize
+ <
+ typename boost::remove_reference
+ <
+ typename traits::interior_mutable_type<Polygon2>::type
+ >::type
+ >::apply(interior_rings(poly2), num_interior_rings(poly1));
+
+ typename interior_return_type<Polygon1 const>::type rings1
+ = interior_rings(poly1);
+ typename interior_return_type<Polygon2>::type rings2
+ = interior_rings(poly2);
+ BOOST_AUTO_TPL(it1, boost::begin(rings1));
+ BOOST_AUTO_TPL(it2, boost::begin(rings2));
+ for ( ; it1 != boost::end(interior_rings(poly1)); ++it1, ++it2)
+ {
+ if (!transform_range_out<point2_type>(*it1,
+ std::back_inserter(*it2), strategy))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
+
+
+template <typename Point1, typename Point2>
+struct select_strategy
+{
+ typedef typename strategy::transform::services::default_strategy
+ <
+ typename cs_tag<Point1>::type,
+ typename cs_tag<Point2>::type,
+ typename coordinate_system<Point1>::type,
+ typename coordinate_system<Point2>::type,
+ dimension<Point1>::type::value,
+ dimension<Point2>::type::value,
+ typename point_type<Point1>::type,
+ typename point_type<Point2>::type
+ >::type type;
+};
+
+template <typename Range1, typename Range2, typename Strategy>
+struct transform_range
+{
+ static inline bool apply(Range1 const& range1,
+ Range2& range2, Strategy const& strategy)
+ {
+ typedef typename point_type<Range2>::type point_type;
+
+ // Should NOT be done here!
+ // geometry::clear(range2);
+ return transform_range_out<point_type>(range1,
+ std::back_inserter(range2), strategy);
+ }
+};
+
+}} // namespace detail::transform
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag1, typename Tag2,
+ typename Geometry1, typename Geometry2,
+ typename Strategy
+>
+struct transform {};
+
+template <typename Point1, typename Point2, typename Strategy>
+struct transform<point_tag, point_tag, Point1, Point2, Strategy>
+ : detail::transform::transform_point<Point1, Point2, Strategy>
+{
+};
+
+
+template <typename Linestring1, typename Linestring2, typename Strategy>
+struct transform
+ <
+ linestring_tag, linestring_tag,
+ Linestring1, Linestring2, Strategy
+ >
+ : detail::transform::transform_range<Linestring1, Linestring2, Strategy>
+{
+};
+
+template <typename Range1, typename Range2, typename Strategy>
+struct transform<ring_tag, ring_tag, Range1, Range2, Strategy>
+ : detail::transform::transform_range<Range1, Range2, Strategy>
+{
+};
+
+template <typename Polygon1, typename Polygon2, typename Strategy>
+struct transform<polygon_tag, polygon_tag, Polygon1, Polygon2, Strategy>
+ : detail::transform::transform_polygon<Polygon1, Polygon2, Strategy>
+{
+};
+
+template <typename Box1, typename Box2, typename Strategy>
+struct transform<box_tag, box_tag, Box1, Box2, Strategy>
+ : detail::transform::transform_box<Box1, Box2, Strategy>
+{
+};
+
+template <typename Segment1, typename Segment2, typename Strategy>
+struct transform<segment_tag, segment_tag, Segment1, Segment2, Strategy>
+ : detail::transform::transform_box_or_segment<Segment1, Segment2, Strategy>
+{
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Transforms from one geometry to another geometry \brief_strategy
+\ingroup transform
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Strategy strategy
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param strategy The strategy to be used for transformation
+\return True if the transformation could be done
+
+\qbk{distinguish,with strategy}
+
+\qbk{[include reference/algorithms/transform_with_strategy.qbk]}
+ */
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2,
+ Strategy const& strategy)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2>();
+
+ typedef dispatch::transform
+ <
+ typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
+ typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
+ Geometry1,
+ Geometry2,
+ Strategy
+ > transform_type;
+
+ return transform_type::apply(geometry1, geometry2, strategy);
+}
+
+
+/*!
+\brief Transforms from one geometry to another geometry using a strategy
+\ingroup transform
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\return True if the transformation could be done
+
+\qbk{[include reference/algorithms/transform.qbk]}
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2>();
+
+ typename detail::transform::select_strategy<Geometry1, Geometry2>::type strategy;
+ return transform(geometry1, geometry2, strategy);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_TRANSFORM_HPP
diff --git a/src/boost/geometry/algorithms/union.hpp b/src/boost/geometry/algorithms/union.hpp
new file mode 100644
index 0000000..28d8e5d
--- /dev/null
+++ b/src/boost/geometry/algorithms/union.hpp
@@ -0,0 +1,284 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
+
+
+#include <boost/mpl/if.hpp>
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/core/is_areal.hpp>
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/reverse_dispatch.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ // tag dispatching:
+ typename TagIn1, typename TagIn2, typename TagOut,
+ // metafunction finetuning helpers:
+ bool Areal1, bool Areal2, bool ArealOut,
+ // real types
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator,
+ typename GeometryOut,
+ typename Strategy
+>
+struct union_insert
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES
+ , (types<Geometry1, Geometry2, GeometryOut>)
+ );
+};
+
+
+template
+<
+ typename TagIn1, typename TagIn2, typename TagOut,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator,
+ typename GeometryOut,
+ typename Strategy
+>
+struct union_insert
+ <
+ TagIn1, TagIn2, TagOut,
+ true, true, true,
+ Geometry1, Geometry2,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ Strategy
+ > : detail::overlay::overlay
+ <Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, overlay_union, Strategy>
+{};
+
+
+
+template
+<
+ typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
+ bool Areal1, bool Areal2, bool ArealOut,
+ typename Geometry1, typename Geometry2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ typename Strategy
+>
+struct union_insert_reversed
+{
+ static inline OutputIterator apply(Geometry1 const& g1,
+ Geometry2 const& g2, OutputIterator out,
+ Strategy const& strategy)
+ {
+ return union_insert
+ <
+ GeometryTag2, GeometryTag1, GeometryTag3,
+ Areal2, Areal1, ArealOut,
+ Geometry2, Geometry1,
+ Reverse2, Reverse1, ReverseOut,
+ OutputIterator, GeometryOut,
+ Strategy
+ >::apply(g2, g1, out, strategy);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace union_
+{
+
+template
+<
+ typename GeometryOut,
+ typename Geometry1, typename Geometry2,
+ typename OutputIterator,
+ typename Strategy
+>
+inline OutputIterator insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out,
+ Strategy const& strategy)
+{
+ return boost::mpl::if_c
+ <
+ geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
+ dispatch::union_insert_reversed
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag<GeometryOut>::type,
+ geometry::is_areal<Geometry1>::value,
+ geometry::is_areal<Geometry2>::value,
+ geometry::is_areal<GeometryOut>::value,
+ Geometry1, Geometry2,
+ overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
+ overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
+ OutputIterator, GeometryOut,
+ Strategy
+ >,
+ dispatch::union_insert
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag<GeometryOut>::type,
+ geometry::is_areal<Geometry1>::value,
+ geometry::is_areal<Geometry2>::value,
+ geometry::is_areal<GeometryOut>::value,
+ Geometry1, Geometry2,
+ overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
+ overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
+ OutputIterator, GeometryOut,
+ Strategy
+ >
+ >::type::apply(geometry1, geometry2, out, strategy);
+}
+
+/*!
+\brief_calc2{union} \brief_strategy
+\ingroup union
+\details \details_calc2{union_insert, spatial set theoretic union}
+ \brief_strategy. details_insert{union}
+\tparam GeometryOut output geometry type, must be specified
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam OutputIterator output iterator
+\tparam Strategy \tparam_strategy_overlay
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param out \param_out{union}
+\param strategy \param_strategy{union}
+\return \return_out
+
+\qbk{distinguish,with strategy}
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator,
+ typename Strategy
+>
+inline OutputIterator union_insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out,
+ Strategy const& strategy)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ concept::check<GeometryOut>();
+
+ return detail::union_::insert<GeometryOut>(geometry1, geometry2, out, strategy);
+}
+
+/*!
+\brief_calc2{union}
+\ingroup union
+\details \details_calc2{union_insert, spatial set theoretic union}.
+ \details_insert{union}
+\tparam GeometryOut output geometry type, must be specified
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam OutputIterator output iterator
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param out \param_out{union}
+\return \return_out
+*/
+template
+<
+ typename GeometryOut,
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputIterator
+>
+inline OutputIterator union_insert(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ concept::check<GeometryOut>();
+
+ typedef strategy_intersection
+ <
+ typename cs_tag<GeometryOut>::type,
+ Geometry1,
+ Geometry2,
+ typename geometry::point_type<GeometryOut>::type
+ > strategy;
+
+ return union_insert<GeometryOut>(geometry1, geometry2, out, strategy());
+}
+
+
+}} // namespace detail::union_
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+/*!
+\brief Combines two geometries which each other
+\ingroup union
+\details \details_calc2{union, spatial set theoretic union}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\tparam Collection output collection, either a multi-geometry,
+ or a std::vector<Geometry> / std::deque<Geometry> etc
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param output_collection the output collection
+\note Called union_ because union is a reserved word.
+
+\qbk{[include reference/algorithms/union.qbk]}
+*/
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Collection
+>
+inline void union_(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Collection& output_collection)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
+ typedef typename boost::range_value<Collection>::type geometry_out;
+ concept::check<geometry_out>();
+
+ detail::union_::union_insert<geometry_out>(geometry1, geometry2,
+ std::back_inserter(output_collection));
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
diff --git a/src/boost/geometry/algorithms/unique.hpp b/src/boost/geometry/algorithms/unique.hpp
new file mode 100644
index 0000000..3bbf479
--- /dev/null
+++ b/src/boost/geometry/algorithms/unique.hpp
@@ -0,0 +1,153 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP
+
+#include <algorithm>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace unique
+{
+
+
+template <typename Range, typename ComparePolicy>
+struct range_unique
+{
+ static inline void apply(Range& range, ComparePolicy const& policy)
+ {
+ typename boost::range_iterator<Range>::type it
+ = std::unique
+ (
+ boost::begin(range),
+ boost::end(range),
+ policy
+ );
+
+ traits::resize<Range>::apply(range, it - boost::begin(range));
+ }
+};
+
+
+template <typename Polygon, typename ComparePolicy>
+struct polygon_unique
+{
+ static inline void apply(Polygon& polygon, ComparePolicy const& policy)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ typedef range_unique<ring_type, ComparePolicy> per_range;
+ per_range::apply(exterior_ring(polygon), policy);
+
+ typename interior_return_type<Polygon>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ per_range::apply(*it, policy);
+ }
+ }
+};
+
+
+
+}} // namespace detail::unique
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename ComparePolicy
+>
+struct unique
+{
+ static inline void apply(Geometry&, ComparePolicy const& )
+ {}
+};
+
+
+template <typename Ring, typename ComparePolicy>
+struct unique<ring_tag, Ring, ComparePolicy>
+ : detail::unique::range_unique<Ring, ComparePolicy>
+{};
+
+
+template <typename LineString, typename ComparePolicy>
+struct unique<linestring_tag, LineString, ComparePolicy>
+ : detail::unique::range_unique<LineString, ComparePolicy>
+{};
+
+
+template <typename Polygon, typename ComparePolicy>
+struct unique<polygon_tag, Polygon, ComparePolicy>
+ : detail::unique::polygon_unique<Polygon, ComparePolicy>
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief \brief_calc{minimal set}
+\ingroup unique
+\details \details_calc{unique,minimal set (where duplicate consecutive points are removed)}.
+\tparam Geometry \tparam_geometry
+\param geometry \param_geometry which will be made unique
+
+\qbk{[include reference/algorithms/unique.qbk]}
+*/
+template <typename Geometry>
+inline void unique(Geometry& geometry)
+{
+ concept::check<Geometry>();
+
+ // Default strategy is the default point-comparison policy
+ typedef geometry::equal_to
+ <
+ typename geometry::point_type<Geometry>::type
+ > policy;
+
+
+ dispatch::unique
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ policy
+ >::apply(geometry, policy());
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_UNIQUE_HPP
diff --git a/src/boost/geometry/algorithms/within.hpp b/src/boost/geometry/algorithms/within.hpp
new file mode 100644
index 0000000..f1f0993
--- /dev/null
+++ b/src/boost/geometry/algorithms/within.hpp
@@ -0,0 +1,344 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
+
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/algorithms/make.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/within.hpp>
+#include <boost/geometry/strategies/concepts/within_concept.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/order_as_direction.hpp>
+#include <boost/geometry/views/closeable_view.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within
+{
+
+
+template
+<
+ typename Point,
+ typename Ring,
+ iterate_direction Direction,
+ closure_selector Closure,
+ typename Strategy
+>
+struct point_in_ring
+{
+ BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
+
+ static inline int apply(Point const& point, Ring const& ring,
+ Strategy const& strategy)
+ {
+ if (int(boost::size(ring))
+ < core_detail::closure::minimum_ring_size<Closure>::value)
+ {
+ return -1;
+ }
+
+ typedef typename reversible_view<Ring const, Direction>::type rev_view_type;
+ typedef typename closeable_view
+ <
+ rev_view_type const, Closure
+ >::type cl_view_type;
+ typedef typename boost::range_iterator<cl_view_type const>::type iterator_type;
+
+ rev_view_type rev_view(ring);
+ cl_view_type view(rev_view);
+ typename Strategy::state_type state;
+ iterator_type it = boost::begin(view);
+ iterator_type end = boost::end(view);
+
+ bool stop = false;
+ for (iterator_type previous = it++;
+ it != end && ! stop;
+ ++previous, ++it)
+ {
+ if (! strategy.apply(point, *previous, *it, state))
+ {
+ stop = true;
+ }
+ }
+
+ return strategy.result(state);
+ }
+};
+
+
+// Polygon: in exterior ring, and if so, not within interior ring(s)
+template
+<
+ typename Point,
+ typename Polygon,
+ iterate_direction Direction,
+ closure_selector Closure,
+ typename Strategy
+>
+struct point_in_polygon
+{
+ BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
+
+ static inline int apply(Point const& point, Polygon const& poly,
+ Strategy const& strategy)
+ {
+ int const code = point_in_ring
+ <
+ Point,
+ typename ring_type<Polygon>::type,
+ Direction,
+ Closure,
+ Strategy
+ >::apply(point, exterior_ring(poly), strategy);
+
+ if (code == 1)
+ {
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings));
+ it != boost::end(rings);
+ ++it)
+ {
+ int const interior_code = point_in_ring
+ <
+ Point,
+ typename ring_type<Polygon>::type,
+ Direction,
+ Closure,
+ Strategy
+ >::apply(point, *it, strategy);
+
+ if (interior_code != -1)
+ {
+ // If 0, return 0 (touch)
+ // If 1 (inside hole) return -1 (outside polygon)
+ // If -1 (outside hole) check other holes if any
+ return -interior_code;
+ }
+ }
+ }
+ return code;
+ }
+};
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Tag1 = typename tag<Geometry1>::type,
+ typename Tag2 = typename tag<Geometry2>::type
+>
+struct within: not_implemented<Tag1, Tag2>
+{};
+
+
+template <typename Point, typename Box>
+struct within<Point, Box, point_tag, box_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
+ {
+ return strategy.apply(point, box);
+ }
+};
+
+template <typename Box1, typename Box2>
+struct within<Box1, Box2, box_tag, box_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
+ {
+ assert_dimension_equal<Box1, Box2>();
+ return strategy.apply(box1, box2);
+ }
+};
+
+
+
+template <typename Point, typename Ring>
+struct within<Point, Ring, point_tag, ring_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
+ {
+ return detail::within::point_in_ring
+ <
+ Point,
+ Ring,
+ order_as_direction<geometry::point_order<Ring>::value>::value,
+ geometry::closure<Ring>::value,
+ Strategy
+ >::apply(point, ring, strategy) == 1;
+ }
+};
+
+template <typename Point, typename Polygon>
+struct within<Point, Polygon, point_tag, polygon_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
+ {
+ return detail::within::point_in_polygon
+ <
+ Point,
+ Polygon,
+ order_as_direction<geometry::point_order<Polygon>::value>::value,
+ geometry::closure<Polygon>::value,
+ Strategy
+ >::apply(point, polygon, strategy) == 1;
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_check12{is completely inside}
+\ingroup within
+\details \details_check12{within, is completely inside}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry which might be within the second geometry
+\param geometry2 \param_geometry which might contain the first geometry
+\return true if geometry1 is completely contained within geometry2,
+ else false
+\note The default strategy is used for within detection
+
+
+\qbk{[include reference/algorithms/within.qbk]}
+
+\qbk{
+[heading Example]
+[within]
+[within_output]
+}
+ */
+template<typename Geometry1, typename Geometry2>
+inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typedef typename point_type<Geometry1>::type point_type1;
+ typedef typename point_type<Geometry2>::type point_type2;
+
+ typedef typename strategy::within::services::default_strategy
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag<Geometry1>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ typename tag_cast
+ <
+ typename cs_tag<point_type1>::type, spherical_tag
+ >::type,
+ typename tag_cast
+ <
+ typename cs_tag<point_type2>::type, spherical_tag
+ >::type,
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
+ return dispatch::within
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, strategy_type());
+}
+
+/*!
+\brief \brief_check12{is completely inside} \brief_strategy
+\ingroup within
+\details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry which might be within the second geometry
+\param geometry2 \param_geometry which might contain the first geometry
+\param strategy strategy to be used
+\return true if geometry1 is completely contained within geometry2,
+ else false
+
+\qbk{distinguish,with strategy}
+\qbk{[include reference/algorithms/within.qbk]}
+\qbk{
+[heading Available Strategies]
+\* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
+\* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
+\* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
+
+[heading Example]
+[within_strategy]
+[within_strategy_output]
+
+}
+*/
+template<typename Geometry1, typename Geometry2, typename Strategy>
+inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ concept::within::check
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ Strategy
+ >();
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ return dispatch::within
+ <
+ Geometry1,
+ Geometry2
+ >::apply(geometry1, geometry2, strategy);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
diff --git a/src/boost/geometry/arithmetic/arithmetic.hpp b/src/boost/geometry/arithmetic/arithmetic.hpp
new file mode 100644
index 0000000..6479ecc
--- /dev/null
+++ b/src/boost/geometry/arithmetic/arithmetic.hpp
@@ -0,0 +1,281 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ARITHMETIC_ARITHMETIC_HPP
+#define BOOST_GEOMETRY_ARITHMETIC_ARITHMETIC_HPP
+
+#include <functional>
+
+#include <boost/call_traits.hpp>
+#include <boost/concept/requires.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/util/for_each_coordinate.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename P>
+struct param
+{
+ typedef typename boost::call_traits
+ <
+ typename coordinate_type<P>::type
+ >::param_type type;
+};
+
+
+template <typename C, template <typename> class Function>
+struct value_operation
+{
+ C m_value;
+
+ inline value_operation(C const &value)
+ : m_value(value)
+ {}
+
+ template <typename P, int I>
+ inline void apply(P& point) const
+ {
+ set<I>(point, Function<C>()(get<I>(point), m_value));
+ }
+};
+
+template <typename PointSrc, template <typename> class Function>
+struct point_operation
+{
+ typedef typename coordinate_type<PointSrc>::type coordinate_type;
+ PointSrc const& m_source_point;
+
+ inline point_operation(PointSrc const& point)
+ : m_source_point(point)
+ {}
+
+ template <typename PointDst, int I>
+ inline void apply(PointDst& dest_point) const
+ {
+ set<I>(dest_point,
+ Function<coordinate_type>()(get<I>(dest_point), get<I>(m_source_point)));
+ }
+};
+
+
+template <typename C>
+struct value_assignment
+{
+ C m_value;
+
+ inline value_assignment(C const &value)
+ : m_value(value)
+ {}
+
+ template <typename P, int I>
+ inline void apply(P& point) const
+ {
+ set<I>(point, m_value);
+ }
+};
+
+template <typename PointSrc>
+struct point_assignment
+{
+ PointSrc const& m_source_point;
+
+ inline point_assignment(PointSrc const& point)
+ : m_source_point(point)
+ {}
+
+ template <typename PointDst, int I>
+ inline void apply(PointDst& dest_point) const
+ {
+ set<I>(dest_point, get<I>(m_source_point));
+ }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+ \brief Adds the same value to each coordinate of a point
+ \ingroup arithmetic
+ \details
+ \param p point
+ \param value value to add
+ */
+template <typename Point>
+inline void add_value(Point& p, typename detail::param<Point>::type value)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::plus>(value));
+}
+
+/*!
+ \brief Adds a point to another
+ \ingroup arithmetic
+ \details The coordinates of the second point will be added to those of the first point.
+ The second point is not modified.
+ \param p1 first point
+ \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void add_point(Point1& p1, Point2 const& p2)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+ for_each_coordinate(p1, detail::point_operation<Point2, std::plus>(p2));
+}
+
+/*!
+ \brief Subtracts the same value to each coordinate of a point
+ \ingroup arithmetic
+ \details
+ \param p point
+ \param value value to subtract
+ */
+template <typename Point>
+inline void subtract_value(Point& p, typename detail::param<Point>::type value)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::minus>(value));
+}
+
+/*!
+ \brief Subtracts a point to another
+ \ingroup arithmetic
+ \details The coordinates of the second point will be subtracted to those of the first point.
+ The second point is not modified.
+ \param p1 first point
+ \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void subtract_point(Point1& p1, Point2 const& p2)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+ for_each_coordinate(p1, detail::point_operation<Point2, std::minus>(p2));
+}
+
+/*!
+ \brief Multiplies each coordinate of a point by the same value
+ \ingroup arithmetic
+ \details
+ \param p point
+ \param value value to multiply by
+ */
+template <typename Point>
+inline void multiply_value(Point& p, typename detail::param<Point>::type value)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::multiplies>(value));
+}
+
+/*!
+ \brief Multiplies a point by another
+ \ingroup arithmetic
+ \details The coordinates of the first point will be multiplied by those of the second point.
+ The second point is not modified.
+ \param p1 first point
+ \param p2 second point
+ \note This is *not* a dot, cross or wedge product. It is a mere field-by-field multiplication.
+ */
+template <typename Point1, typename Point2>
+inline void multiply_point(Point1& p1, Point2 const& p2)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+ for_each_coordinate(p1, detail::point_operation<Point2, std::multiplies>(p2));
+}
+
+/*!
+ \brief Divides each coordinate of the same point by a value
+ \ingroup arithmetic
+ \details
+ \param p point
+ \param value value to divide by
+ */
+template <typename Point>
+inline void divide_value(Point& p, typename detail::param<Point>::type value)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::divides>(value));
+}
+
+/*!
+ \brief Divides a point by another
+ \ingroup arithmetic
+ \details The coordinates of the first point will be divided by those of the second point.
+ The second point is not modified.
+ \param p1 first point
+ \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void divide_point(Point1& p1, Point2 const& p2)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+ for_each_coordinate(p1, detail::point_operation<Point2, std::divides>(p2));
+}
+
+/*!
+ \brief Assign each coordinate of a point the same value
+ \ingroup arithmetic
+ \details
+ \param p point
+ \param value value to assign
+ */
+template <typename Point>
+inline void assign_value(Point& p, typename detail::param<Point>::type value)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ for_each_coordinate(p, detail::value_assignment<typename coordinate_type<Point>::type>(value));
+}
+
+/*!
+ \brief Assign a point with another
+ \ingroup arithmetic
+ \details The coordinates of the first point will be assigned those of the second point.
+ The second point is not modified.
+ \param p1 first point
+ \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void assign_point(Point1& p1, const Point2& p2)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+ for_each_coordinate(p1, detail::point_assignment<Point2>(p2));
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ARITHMETIC_ARITHMETIC_HPP
diff --git a/src/boost/geometry/arithmetic/determinant.hpp b/src/boost/geometry/arithmetic/determinant.hpp
new file mode 100644
index 0000000..db3b867
--- /dev/null
+++ b/src/boost/geometry/arithmetic/determinant.hpp
@@ -0,0 +1,76 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ARITHMETIC_DETERMINANT_HPP
+#define BOOST_GEOMETRY_ARITHMETIC_DETERMINANT_HPP
+
+
+#include <cstddef>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename ReturnType, typename U, typename V>
+class calculate_determinant
+{
+ template <typename T>
+ static inline ReturnType rt(T const& v)
+ {
+ return boost::numeric_cast<ReturnType>(v);
+ }
+
+public :
+
+ static inline ReturnType apply(U const& ux, U const& uy
+ , V const& vx, V const& vy)
+ {
+ return rt(ux) * rt(vy) - rt(uy) * rt(vx);
+ }
+};
+
+template <typename ReturnType, typename U, typename V>
+inline ReturnType determinant(U const& ux, U const& uy
+ , V const& vx, V const& vy)
+{
+ return calculate_determinant
+ <
+ ReturnType, U, V
+ >::apply(ux, uy, vx, vy);
+}
+
+
+template <typename ReturnType, typename U, typename V>
+inline ReturnType determinant(U const& u, V const& v)
+{
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<U>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<V>) );
+
+ return calculate_determinant
+ <
+ ReturnType,
+ typename geometry::coordinate_type<U>::type,
+ typename geometry::coordinate_type<V>::type
+ >::apply(get<0>(u), get<1>(u), get<0>(v), get<1>(v));
+}
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ARITHMETIC_DETERMINANT_HPP
diff --git a/src/boost/geometry/arithmetic/dot_product.hpp b/src/boost/geometry/arithmetic/dot_product.hpp
new file mode 100644
index 0000000..13fe968
--- /dev/null
+++ b/src/boost/geometry/arithmetic/dot_product.hpp
@@ -0,0 +1,82 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ARITHMETIC_DOT_PRODUCT_HPP
+#define BOOST_GEOMETRY_ARITHMETIC_DOT_PRODUCT_HPP
+
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P1, typename P2, std::size_t Dimension, std::size_t DimensionCount>
+struct dot_product_maker
+{
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+ static inline coordinate_type apply(P1 const& p1, P2 const& p2)
+ {
+ return get<Dimension>(p1) * get<Dimension>(p2)
+ + dot_product_maker<P1, P2, Dimension+1, DimensionCount>::apply(p1, p2);
+ }
+};
+
+template <typename P1, typename P2, std::size_t DimensionCount>
+struct dot_product_maker<P1, P2, DimensionCount, DimensionCount>
+{
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+ static inline coordinate_type apply(P1 const& p1, P2 const& p2)
+ {
+ return get<DimensionCount>(p1) * get<DimensionCount>(p2);
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+ \brief Computes the dot product (or scalar product) of 2 vectors (points).
+ \ingroup arithmetic
+ \param p1 first point
+ \param p2 second point
+ \return the dot product
+ */
+template <typename P1, typename P2>
+inline typename select_coordinate_type<P1, P2>::type dot_product(
+ P1 const& p1, P2 const& p2)
+{
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P1>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P2>) );
+
+ return detail::dot_product_maker
+ <
+ P1, P2,
+ 0, dimension<P1>::type::value - 1
+ >::apply(p1, p2);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ARITHMETIC_DOT_PRODUCT_HPP
diff --git a/src/boost/geometry/core/access.hpp b/src/boost/geometry/core/access.hpp
new file mode 100644
index 0000000..a463b8c
--- /dev/null
+++ b/src/boost/geometry/core/access.hpp
@@ -0,0 +1,324 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_ACCESS_HPP
+#define BOOST_GEOMETRY_CORE_ACCESS_HPP
+
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/// Index of minimum corner of the box.
+int const min_corner = 0;
+
+/// Index of maximum corner of the box.
+int const max_corner = 1;
+
+namespace traits
+{
+
+/*!
+\brief Traits class which gives access (get,set) to points.
+\ingroup traits
+\par Geometries:
+/// @li point
+\par Specializations should provide, per Dimension
+/// @li static inline T get(G const&)
+/// @li static inline void set(G&, T const&)
+\tparam Geometry geometry-type
+\tparam Dimension dimension to access
+*/
+template <typename Geometry, std::size_t Dimension, typename Enable = void>
+struct access
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Geometry>)
+ );
+};
+
+
+/*!
+\brief Traits class defining "get" and "set" to get
+ and set point coordinate values
+\tparam Geometry geometry (box, segment)
+\tparam Index index (min_corner/max_corner for box, 0/1 for segment)
+\tparam Dimension dimension
+\par Geometries:
+ - box
+ - segment
+\par Specializations should provide:
+ - static inline T get(G const&)
+ - static inline void set(G&, T const&)
+\ingroup traits
+*/
+template <typename Geometry, std::size_t Index, std::size_t Dimension>
+struct indexed_access {};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename
+ CoordinateType, std::size_t Dimension
+>
+struct access
+{
+ //static inline T get(G const&) {}
+ //static inline void set(G& g, T const& value) {}
+};
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename CoordinateType,
+ std::size_t Index,
+ std::size_t Dimension
+>
+struct indexed_access
+{
+ //static inline T get(G const&) {}
+ //static inline void set(G& g, T const& value) {}
+};
+
+template <typename Point, typename CoordinateType, std::size_t Dimension>
+struct access<point_tag, Point, CoordinateType, Dimension>
+{
+ static inline CoordinateType get(Point const& point)
+ {
+ return traits::access<Point, Dimension>::get(point);
+ }
+ static inline void set(Point& p, CoordinateType const& value)
+ {
+ traits::access<Point, Dimension>::set(p, value);
+ }
+};
+
+template
+<
+ typename Box,
+ typename CoordinateType,
+ std::size_t Index,
+ std::size_t Dimension
+>
+struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension>
+{
+ static inline CoordinateType get(Box const& box)
+ {
+ return traits::indexed_access<Box, Index, Dimension>::get(box);
+ }
+ static inline void set(Box& b, CoordinateType const& value)
+ {
+ traits::indexed_access<Box, Index, Dimension>::set(b, value);
+ }
+};
+
+template
+<
+ typename Segment,
+ typename CoordinateType,
+ std::size_t Index,
+ std::size_t Dimension
+>
+struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension>
+{
+ static inline CoordinateType get(Segment const& segment)
+ {
+ return traits::indexed_access<Segment, Index, Dimension>::get(segment);
+ }
+ static inline void set(Segment& segment, CoordinateType const& value)
+ {
+ traits::indexed_access<Segment, Index, Dimension>::set(segment, value);
+ }
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Two dummy tags to distinguish get/set variants below.
+// They don't have to be specified by the user. The functions are distinguished
+// by template signature also, but for e.g. GCC this is not enough. So give them
+// a different signature.
+struct signature_getset_dimension {};
+struct signature_getset_index_dimension {};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Get coordinate value of a geometry (usually a point)
+\details \details_get_set
+\ingroup get
+\tparam Dimension \tparam_dimension_required
+\tparam Geometry \tparam_geometry (usually a Point Concept)
+\param geometry \param_geometry (usually a point)
+\param dummy \qbk_skip
+\return The coordinate value of specified dimension of specified geometry
+\qbk{[include reference/core/get_point.qbk]}
+*/
+template <std::size_t Dimension, typename Geometry>
+inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
+ , detail::signature_getset_dimension* dummy = 0
+ )
+{
+ boost::ignore_unused_variable_warning(dummy);
+
+ typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+ typedef core_dispatch::access
+ <
+ typename tag<Geometry>::type,
+ ncg_type,
+ typename coordinate_type<ncg_type>::type,
+ Dimension
+ > coord_access_type;
+
+ return coord_access_type::get(geometry);
+}
+
+
+/*!
+\brief Set coordinate value of a geometry (usually a point)
+\details \details_get_set
+\tparam Dimension \tparam_dimension_required
+\tparam Geometry \tparam_geometry (usually a Point Concept)
+\param geometry geometry to assign coordinate to
+\param geometry \param_geometry (usually a point)
+\param value The coordinate value to set
+\param dummy \qbk_skip
+\ingroup set
+
+\qbk{[include reference/core/set_point.qbk]}
+*/
+template <std::size_t Dimension, typename Geometry>
+inline void set(Geometry& geometry
+ , typename coordinate_type<Geometry>::type const& value
+ , detail::signature_getset_dimension* dummy = 0
+ )
+{
+ boost::ignore_unused_variable_warning(dummy);
+
+ typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+ typedef core_dispatch::access
+ <
+ typename tag<Geometry>::type,
+ ncg_type,
+ typename coordinate_type<ncg_type>::type,
+ Dimension
+ > coord_access_type;
+
+ coord_access_type::set(geometry, value);
+}
+
+
+/*!
+\brief get coordinate value of a Box or Segment
+\details \details_get_set
+\tparam Index \tparam_index_required
+\tparam Dimension \tparam_dimension_required
+\tparam Geometry \tparam_box_or_segment
+\param geometry \param_geometry
+\param dummy \qbk_skip
+\return coordinate value
+\ingroup get
+
+\qbk{distinguish,with index}
+\qbk{[include reference/core/get_box.qbk]}
+*/
+template <std::size_t Index, std::size_t Dimension, typename Geometry>
+inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
+ , detail::signature_getset_index_dimension* dummy = 0
+ )
+{
+ boost::ignore_unused_variable_warning(dummy);
+
+ typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+ typedef core_dispatch::indexed_access
+ <
+ typename tag<Geometry>::type,
+ ncg_type,
+ typename coordinate_type<ncg_type>::type,
+ Index,
+ Dimension
+ > coord_access_type;
+
+ return coord_access_type::get(geometry);
+}
+
+/*!
+\brief set coordinate value of a Box / Segment
+\details \details_get_set
+\tparam Index \tparam_index_required
+\tparam Dimension \tparam_dimension_required
+\tparam Geometry \tparam_box_or_segment
+\param geometry geometry to assign coordinate to
+\param geometry \param_geometry
+\param value The coordinate value to set
+\param dummy \qbk_skip
+\ingroup set
+
+\qbk{distinguish,with index}
+\qbk{[include reference/core/set_box.qbk]}
+*/
+template <std::size_t Index, std::size_t Dimension, typename Geometry>
+inline void set(Geometry& geometry
+ , typename coordinate_type<Geometry>::type const& value
+ , detail::signature_getset_index_dimension* dummy = 0
+ )
+{
+ boost::ignore_unused_variable_warning(dummy);
+
+ typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+ typedef core_dispatch::indexed_access
+ <
+ typename tag<Geometry>::type, ncg_type,
+ typename coordinate_type<ncg_type>::type,
+ Index,
+ Dimension
+ > coord_access_type;
+
+ coord_access_type::set(geometry, value);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_ACCESS_HPP
diff --git a/src/boost/geometry/core/closure.hpp b/src/boost/geometry/core/closure.hpp
new file mode 100644
index 0000000..aab02e7
--- /dev/null
+++ b/src/boost/geometry/core/closure.hpp
@@ -0,0 +1,180 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_CLOSURE_HPP
+#define BOOST_GEOMETRY_CORE_CLOSURE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief Enumerates options for defining if polygons are open or closed
+\ingroup enum
+\details The enumeration closure_selector describes options for if a polygon is
+ open or closed. In a closed polygon the very first point (per ring) should
+ be equal to the very last point.
+ The specific closing property of a polygon type is defined by the closure
+ metafunction. The closure metafunction defines a value, which is one of the
+ values enumerated in the closure_selector
+
+\qbk{
+[heading See also]
+[link geometry.reference.core.closure The closure metafunction]
+}
+*/
+enum closure_selector
+{
+ /// Rings are open: first point and last point are different, algorithms
+ /// close them explicitly on the fly
+ open = 0,
+ /// Rings are closed: first point and last point must be the same
+ closed = 1,
+ /// (Not yet implemented): algorithms first figure out if ring must be
+ /// closed on the fly
+ closure_undertermined = -1
+};
+
+namespace traits
+{
+
+/*!
+ \brief Traits class indicating if points within a
+ ring or (multi)polygon are closed (last point == first point),
+ open or not known.
+ \ingroup traits
+ \par Geometries:
+ - ring
+ \tparam G geometry
+*/
+template <typename G>
+struct closure
+{
+ static const closure_selector value = closed;
+};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace core_detail { namespace closure
+{
+
+struct closed
+{
+ static const closure_selector value = geometry::closed;
+};
+
+
+/// Metafunction to define the minimum size of a ring:
+/// 3 for open rings, 4 for closed rings
+template <closure_selector Closure>
+struct minimum_ring_size {};
+
+template <>
+struct minimum_ring_size<geometry::closed> : boost::mpl::int_<4> {};
+
+template <>
+struct minimum_ring_size<geometry::open> : boost::mpl::int_<3> {};
+
+
+}} // namespace detail::point_order
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct closure
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+template <typename Box>
+struct closure<point_tag, Box> : public core_detail::closure::closed {};
+
+template <typename Box>
+struct closure<box_tag, Box> : public core_detail::closure::closed {};
+
+template <typename Box>
+struct closure<segment_tag, Box> : public core_detail::closure::closed {};
+
+template <typename LineString>
+struct closure<linestring_tag, LineString>
+ : public core_detail::closure::closed {};
+
+
+template <typename Ring>
+struct closure<ring_tag, Ring>
+{
+ static const closure_selector value
+ = geometry::traits::closure<Ring>::value;
+};
+
+// Specialization for polygon: the closure is the closure of its rings
+template <typename Polygon>
+struct closure<polygon_tag, Polygon>
+{
+ static const closure_selector value = core_dispatch::closure
+ <
+ ring_tag,
+ typename ring_type<polygon_tag, Polygon>::type
+ >::value ;
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_meta{value, closure (clockwise\, counterclockwise),
+ \meta_geometry_type}
+\tparam Geometry \tparam_geometry
+\ingroup core
+
+\qbk{[include reference/core/closure.qbk]}
+*/
+template <typename Geometry>
+struct closure
+{
+ static const closure_selector value = core_dispatch::closure
+ <
+ typename tag<Geometry>::type,
+ typename boost::remove_const<Geometry>::type
+ >::value;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_CLOSURE_HPP
diff --git a/src/boost/geometry/core/coordinate_dimension.hpp b/src/boost/geometry/core/coordinate_dimension.hpp
new file mode 100644
index 0000000..84c11e2
--- /dev/null
+++ b/src/boost/geometry/core/coordinate_dimension.hpp
@@ -0,0 +1,126 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_COORDINATE_DIMENSION_HPP
+#define BOOST_GEOMETRY_CORE_COORDINATE_DIMENSION_HPP
+
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+/*!
+\brief Traits class indicating the number of dimensions of a point
+\par Geometries:
+ - point
+\par Specializations should provide:
+ - value (should be derived from boost::mpl::int_<D>
+\ingroup traits
+*/
+template <typename Point, typename Enable = void>
+struct dimension
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Point>)
+ );
+};
+
+} // namespace traits
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+// Base class derive from its own specialization of point-tag
+template <typename T, typename G>
+struct dimension : dimension<point_tag, typename point_type<T, G>::type> {};
+
+template <typename P>
+struct dimension<point_tag, P> : traits::dimension<P> {};
+
+} // namespace core_dispatch
+#endif
+
+/*!
+\brief \brief_meta{value, number of coordinates (the number of axes of any geometry), \meta_point_type}
+\tparam Geometry \tparam_geometry
+\ingroup core
+
+\qbk{[include reference/core/coordinate_dimension.qbk]}
+*/
+template <typename Geometry>
+struct dimension
+ : core_dispatch::dimension
+ <
+ typename tag<Geometry>::type,
+ typename boost::remove_const<Geometry>::type
+ >
+{};
+
+/*!
+\brief assert_dimension, enables compile-time checking if coordinate dimensions are as expected
+\ingroup utility
+*/
+template <typename Geometry, int Dimensions>
+inline void assert_dimension()
+{
+ BOOST_STATIC_ASSERT((
+ boost::mpl::equal_to
+ <
+ geometry::dimension<Geometry>,
+ boost::mpl::int_<Dimensions>
+ >::type::value
+ ));
+}
+
+/*!
+\brief assert_dimension, enables compile-time checking if coordinate dimensions are as expected
+\ingroup utility
+*/
+template <typename Geometry, int Dimensions>
+inline void assert_dimension_less_equal()
+{
+ BOOST_STATIC_ASSERT(( dimension<Geometry>::type::value <= Dimensions ));
+}
+
+template <typename Geometry, int Dimensions>
+inline void assert_dimension_greater_equal()
+{
+ BOOST_STATIC_ASSERT(( dimension<Geometry>::type::value >= Dimensions ));
+}
+
+/*!
+\brief assert_dimension_equal, enables compile-time checking if coordinate dimensions of two geometries are equal
+\ingroup utility
+*/
+template <typename G1, typename G2>
+inline void assert_dimension_equal()
+{
+ BOOST_STATIC_ASSERT(( dimension<G1>::type::value == dimension<G2>::type::value ));
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_COORDINATE_DIMENSION_HPP
diff --git a/src/boost/geometry/core/coordinate_system.hpp b/src/boost/geometry/core/coordinate_system.hpp
new file mode 100644
index 0000000..c23b8af
--- /dev/null
+++ b/src/boost/geometry/core/coordinate_system.hpp
@@ -0,0 +1,97 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_COORDINATE_SYSTEM_HPP
+#define BOOST_GEOMETRY_CORE_COORDINATE_SYSTEM_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace traits
+{
+
+/*!
+\brief Traits class defining the coordinate system of a point, important for strategy selection
+\ingroup traits
+\par Geometries:
+ - point
+\par Specializations should provide:
+ - typedef CS type; (cs::cartesian, cs::spherical, etc)
+*/
+template <typename Point, typename Enable = void>
+struct coordinate_system
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Point>)
+ );
+};
+
+} // namespace traits
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+ template <typename GeometryTag, typename G>
+ struct coordinate_system
+ {
+ typedef typename point_type<GeometryTag, G>::type P;
+
+ // Call its own specialization on point-tag
+ typedef typename coordinate_system<point_tag, P>::type type;
+ };
+
+
+ template <typename P>
+ struct coordinate_system<point_tag, P>
+ {
+ typedef typename traits::coordinate_system<P>::type type;
+ };
+
+
+} // namespace core_dispatch
+#endif
+
+
+/*!
+\brief \brief_meta{type, coordinate system (cartesian\, spherical\, etc), \meta_point_type}
+\tparam Geometry \tparam_geometry
+\ingroup core
+
+\qbk{[include reference/core/coordinate_system.qbk]}
+*/
+template <typename Geometry>
+struct coordinate_system
+{
+ typedef typename boost::remove_const<Geometry>::type ncg;
+ typedef typename core_dispatch::coordinate_system
+ <
+ typename tag<Geometry>::type,
+ ncg
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_COORDINATE_SYSTEM_HPP
diff --git a/src/boost/geometry/core/coordinate_type.hpp b/src/boost/geometry/core/coordinate_type.hpp
new file mode 100644
index 0000000..0f901d3
--- /dev/null
+++ b/src/boost/geometry/core/coordinate_type.hpp
@@ -0,0 +1,102 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_COORDINATE_TYPE_HPP
+#define BOOST_GEOMETRY_CORE_COORDINATE_TYPE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+/*!
+\brief Traits class which indicate the coordinate type (double,float,...) of a point
+\ingroup traits
+\par Geometries:
+ - point
+\par Specializations should provide:
+ - typedef T type; (double,float,int,etc)
+*/
+template <typename Point, typename Enable = void>
+struct coordinate_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Point>)
+ );
+};
+
+} // namespace traits
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag, typename Geometry>
+struct coordinate_type
+{
+ typedef typename point_type<GeometryTag, Geometry>::type point_type;
+
+ // Call its own specialization on point-tag
+ typedef typename coordinate_type<point_tag, point_type>::type type;
+};
+
+template <typename Point>
+struct coordinate_type<point_tag, Point>
+{
+ typedef typename traits::coordinate_type<Point>::type type;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+\brief \brief_meta{type, coordinate type (int\, float\, double\, etc), \meta_point_type}
+\tparam Geometry \tparam_geometry
+\ingroup core
+
+\qbk{[include reference/core/coordinate_type.qbk]}
+*/
+template <typename Geometry>
+struct coordinate_type
+{
+ typedef typename core_dispatch::coordinate_type
+ <
+ typename tag<Geometry>::type,
+ typename boost::remove_const<Geometry>::type
+ >::type type;
+};
+
+template <typename Geometry>
+struct fp_coordinate_type
+{
+ typedef typename promote_floating_point
+ <
+ typename coordinate_type<Geometry>::type
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_COORDINATE_TYPE_HPP
diff --git a/src/boost/geometry/core/cs.hpp b/src/boost/geometry/core/cs.hpp
new file mode 100644
index 0000000..3588ed1
--- /dev/null
+++ b/src/boost/geometry/core/cs.hpp
@@ -0,0 +1,220 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_CS_HPP
+#define BOOST_GEOMETRY_CORE_CS_HPP
+
+#include <cstddef>
+
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Unit of plane angle: Degrees
+\details Tag defining the unit of plane angle for spherical coordinate systems.
+ This tag specifies that coordinates are defined in degrees (-180 .. 180).
+ It has to be specified for some coordinate systems.
+\qbk{[include reference/core/degree_radian.qbk]}
+*/
+struct degree {};
+
+
+/*!
+\brief Unit of plane angle: Radians
+\details Tag defining the unit of plane angle for spherical coordinate systems.
+ This tag specifies that coordinates are defined in radians (-PI .. PI).
+ It has to be specified for some coordinate systems.
+\qbk{[include reference/core/degree_radian.qbk]}
+*/
+struct radian {};
+
+
+namespace cs
+{
+
+/*!
+\brief Cartesian coordinate system
+\details Defines the Cartesian or rectangular coordinate system
+ where points are defined in 2 or 3 (or more)
+dimensions and usually (but not always) known as x,y,z
+\see http://en.wikipedia.org/wiki/Cartesian_coordinate_system
+\ingroup cs
+*/
+struct cartesian {};
+
+
+
+
+/*!
+\brief Geographic coordinate system, in degree or in radian
+\details Defines the geographic coordinate system where points
+ are defined in two angles and usually
+known as lat,long or lo,la or phi,lambda
+\see http://en.wikipedia.org/wiki/Geographic_coordinate_system
+\ingroup cs
+\note might be moved to extensions/gis/geographic
+*/
+template<typename DegreeOrRadian>
+struct geographic
+{
+ typedef DegreeOrRadian units;
+};
+
+
+
+/*!
+\brief Spherical (polar) coordinate system, in degree or in radian
+\details Defines the spherical coordinate system where points are
+ defined in two angles
+ and an optional radius usually known as r, theta, phi
+\par Coordinates:
+- coordinate 0:
+ 0 <= phi < 2pi is the angle between the positive x-axis and the
+ line from the origin to the P projected onto the xy-plane.
+- coordinate 1:
+ 0 <= theta <= pi is the angle between the positive z-axis and the
+ line formed between the origin and P.
+- coordinate 2 (if specified):
+ r >= 0 is the distance from the origin to a given point P.
+
+\see http://en.wikipedia.org/wiki/Spherical_coordinates
+\ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct spherical
+{
+ typedef DegreeOrRadian units;
+};
+
+
+/*!
+\brief Spherical equatorial coordinate system, in degree or in radian
+\details This one resembles the geographic coordinate system, and has latitude
+ up from zero at the equator, to 90 at the pole
+ (opposite to the spherical(polar) coordinate system).
+ Used in astronomy and in GIS (but there is also the geographic)
+
+\see http://en.wikipedia.org/wiki/Spherical_coordinates
+\ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct spherical_equatorial
+{
+ typedef DegreeOrRadian units;
+};
+
+
+
+/*!
+\brief Polar coordinate system
+\details Defines the polar coordinate system "in which each point
+ on a plane is determined by an angle and a distance"
+\see http://en.wikipedia.org/wiki/Polar_coordinates
+\ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct polar
+{
+ typedef DegreeOrRadian units;
+};
+
+
+} // namespace cs
+
+
+namespace traits
+{
+
+/*!
+\brief Traits class defining coordinate system tag, bound to coordinate system
+\ingroup traits
+\tparam CoordinateSystem coordinate system
+*/
+template <typename CoordinateSystem>
+struct cs_tag
+{
+};
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+template<typename DegreeOrRadian>
+struct cs_tag<cs::geographic<DegreeOrRadian> >
+{
+ typedef geographic_tag type;
+};
+
+template<typename DegreeOrRadian>
+struct cs_tag<cs::spherical<DegreeOrRadian> >
+{
+ typedef spherical_polar_tag type;
+};
+
+template<typename DegreeOrRadian>
+struct cs_tag<cs::spherical_equatorial<DegreeOrRadian> >
+{
+ typedef spherical_equatorial_tag type;
+};
+
+
+template<>
+struct cs_tag<cs::cartesian>
+{
+ typedef cartesian_tag type;
+};
+
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+} // namespace traits
+
+/*!
+\brief Meta-function returning coordinate system tag (cs family) of any geometry
+\ingroup core
+*/
+template <typename G>
+struct cs_tag
+{
+ typedef typename traits::cs_tag
+ <
+ typename geometry::coordinate_system<G>::type
+ >::type type;
+};
+
+
+/*!
+\brief Meta-function to verify if a coordinate system is radian
+\ingroup core
+*/
+template <typename CoordinateSystem>
+struct is_radian : boost::true_type {};
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+// Specialization for any degree coordinate systems
+template <template<typename> class CoordinateSystem>
+struct is_radian< CoordinateSystem<degree> > : boost::false_type
+{
+};
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_CS_HPP
diff --git a/src/boost/geometry/core/exception.hpp b/src/boost/geometry/core/exception.hpp
new file mode 100644
index 0000000..97d249e
--- /dev/null
+++ b/src/boost/geometry/core/exception.hpp
@@ -0,0 +1,60 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_EXCEPTION_HPP
+#define BOOST_GEOMETRY_CORE_EXCEPTION_HPP
+
+#include <exception>
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Base exception class for Boost.Geometry algorithms
+\ingroup core
+\details This class is never thrown. All exceptions thrown in Boost.Geometry
+ are derived from exception, so it might be convenient to catch it.
+*/
+class exception : public std::exception
+{};
+
+
+/*!
+\brief Empty Input Exception
+\ingroup core
+\details The empty_input_exception is thrown if free functions, e.g. distance,
+ are called with empty geometries, e.g. a linestring
+ without points, a polygon without points, an empty multi-geometry.
+\qbk{
+[heading See also]
+\* [link geometry.reference.algorithms.area the area function]
+\* [link geometry.reference.algorithms.distance the distance function]
+\* [link geometry.reference.algorithms.length the length function]
+}
+ */
+class empty_input_exception : public geometry::exception
+{
+public:
+
+ inline empty_input_exception() {}
+
+ virtual char const* what() const throw()
+ {
+ return "Boost.Geometry Empty-Input exception";
+ }
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_EXCEPTION_HPP
diff --git a/src/boost/geometry/core/exterior_ring.hpp b/src/boost/geometry/core/exterior_ring.hpp
new file mode 100644
index 0000000..70012c2
--- /dev/null
+++ b/src/boost/geometry/core/exterior_ring.hpp
@@ -0,0 +1,144 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_CORE_EXTERIOR_RING_HPP
+#define BOOST_GEOMETRY_CORE_EXTERIOR_RING_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/util/add_const_if_c.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+
+/*!
+ \brief Traits class defining access to exterior_ring of a polygon
+ \details Should define const and non const access
+ \ingroup traits
+ \tparam Polygon the polygon type
+ \par Geometries:
+ - polygon
+ \par Specializations should provide:
+ - static inline RING& get(POLY& )
+ - static inline RING const& get(POLY const& )
+*/
+template <typename Polygon>
+struct exterior_ring
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POLYGON_TYPE
+ , (types<Polygon>)
+ );
+};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename Tag, typename Geometry>
+struct exterior_ring
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename Polygon>
+struct exterior_ring<polygon_tag, Polygon>
+{
+ static
+ typename geometry::ring_return_type<Polygon>::type
+ apply(typename add_const_if_c
+ <
+ boost::is_const<Polygon>::type::value,
+ Polygon
+ >::type& polygon)
+ {
+ return traits::exterior_ring
+ <
+ typename boost::remove_const<Polygon>::type
+ >::get(polygon);
+ }
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Function to get the exterior_ring ring of a polygon
+ \ingroup exterior_ring
+ \note OGC compliance: instead of ExteriorRing
+ \tparam P polygon type
+ \param polygon the polygon to get the exterior ring from
+ \return a reference to the exterior ring
+*/
+template <typename Polygon>
+inline typename ring_return_type<Polygon>::type exterior_ring(Polygon& polygon)
+{
+ return core_dispatch::exterior_ring
+ <
+ typename tag<Polygon>::type,
+ Polygon
+ >::apply(polygon);
+}
+
+
+/*!
+\brief Function to get the exterior ring of a polygon (const version)
+\ingroup exterior_ring
+\note OGC compliance: instead of ExteriorRing
+\tparam Polygon polygon type
+\param polygon the polygon to get the exterior ring from
+\return a const reference to the exterior ring
+
+\qbk{distinguish,const version}
+*/
+template <typename Polygon>
+inline typename ring_return_type<Polygon const>::type exterior_ring(
+ Polygon const& polygon)
+{
+ return core_dispatch::exterior_ring
+ <
+ typename tag<Polygon>::type,
+ Polygon const
+ >::apply(polygon);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_EXTERIOR_RING_HPP
diff --git a/src/boost/geometry/core/geometry_id.hpp b/src/boost/geometry/core/geometry_id.hpp
new file mode 100644
index 0000000..369c5cf
--- /dev/null
+++ b/src/boost/geometry/core/geometry_id.hpp
@@ -0,0 +1,94 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_CORE_GEOMETRY_ID_HPP
+#define BOOST_GEOMETRY_CORE_GEOMETRY_ID_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag>
+struct geometry_id
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<GeometryTag>)
+ );
+};
+
+
+template <>
+struct geometry_id<point_tag> : boost::mpl::int_<1> {};
+
+
+template <>
+struct geometry_id<linestring_tag> : boost::mpl::int_<2> {};
+
+
+template <>
+struct geometry_id<polygon_tag> : boost::mpl::int_<3> {};
+
+
+template <>
+struct geometry_id<segment_tag> : boost::mpl::int_<92> {};
+
+
+template <>
+struct geometry_id<ring_tag> : boost::mpl::int_<93> {};
+
+
+template <>
+struct geometry_id<box_tag> : boost::mpl::int_<94> {};
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+/*!
+\brief Meta-function returning the id of a geometry type
+\details The meta-function geometry_id defines a numerical ID (based on
+ boost::mpl::int_<...> ) for each geometry concept. A numerical ID is
+ sometimes useful, and within Boost.Geometry it is used for the
+ reverse_dispatch metafuntion.
+\note Used for e.g. reverse meta-function
+\ingroup core
+*/
+template <typename Geometry>
+struct geometry_id : core_dispatch::geometry_id<typename tag<Geometry>::type>
+{};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_GEOMETRY_ID_HPP
diff --git a/src/boost/geometry/core/interior_rings.hpp b/src/boost/geometry/core/interior_rings.hpp
new file mode 100644
index 0000000..10af2ae
--- /dev/null
+++ b/src/boost/geometry/core/interior_rings.hpp
@@ -0,0 +1,139 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_INTERIOR_RINGS_HPP
+#define BOOST_GEOMETRY_CORE_INTERIOR_RINGS_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/interior_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+
+/*!
+ \brief Traits class defining access to interior_rings of a polygon
+ \details defines access (const and non const) to interior ring
+ \ingroup traits
+ \par Geometries:
+ - polygon
+ \par Specializations should provide:
+ - static inline INTERIOR& get(POLY&)
+ - static inline const INTERIOR& get(POLY const&)
+ \tparam Geometry geometry
+*/
+template <typename Geometry>
+struct interior_rings
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+} // namespace traits
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template
+<
+ typename GeometryTag,
+ typename Geometry
+>
+struct interior_rings {};
+
+
+template <typename Polygon>
+struct interior_rings<polygon_tag, Polygon>
+{
+ static inline
+ typename geometry::interior_return_type<Polygon>::type
+ apply(Polygon& polygon)
+ {
+ return traits::interior_rings
+ <
+ typename boost::remove_const<Polygon>::type
+ >::get(polygon);
+ }
+};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+/*!
+\brief Function to get the interior rings of a polygon (non const version)
+\ingroup interior_rings
+\note OGC compliance: instead of InteriorRingN
+\tparam Polygon polygon type
+\param polygon the polygon to get the interior rings from
+\return the interior rings (possibly a reference)
+*/
+
+template <typename Polygon>
+inline typename interior_return_type<Polygon>::type interior_rings(Polygon& polygon)
+{
+ return core_dispatch::interior_rings
+ <
+ typename tag<Polygon>::type,
+ Polygon
+ >::apply(polygon);
+}
+
+
+/*!
+\brief Function to get the interior rings of a polygon (const version)
+\ingroup interior_rings
+\note OGC compliance: instead of InteriorRingN
+\tparam Polygon polygon type
+\param polygon the polygon to get the interior rings from
+\return the interior rings (possibly a const reference)
+
+\qbk{distinguish,const version}
+*/
+template <typename Polygon>
+inline typename interior_return_type<Polygon const>::type interior_rings(
+ Polygon const& polygon)
+{
+ return core_dispatch::interior_rings
+ <
+ typename tag<Polygon>::type,
+ Polygon const
+ >::apply(polygon);
+}
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_INTERIOR_RINGS_HPP
diff --git a/src/boost/geometry/core/interior_type.hpp b/src/boost/geometry/core/interior_type.hpp
new file mode 100644
index 0000000..0232837
--- /dev/null
+++ b/src/boost/geometry/core/interior_type.hpp
@@ -0,0 +1,161 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_CORE_INTERIOR_TYPE_HPP
+#define BOOST_GEOMETRY_CORE_INTERIOR_TYPE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+/*!
+\brief Traits class indicating interior container type of a polygon
+\details defines inner container type, so the container containing
+ the interior rings
+\ingroup traits
+\par Geometries:
+ - polygon
+\par Specializations should provide:
+ - typedef X type ( e.g. std::vector<myring<P>> )
+\tparam Geometry geometry
+*/
+template <typename Geometry>
+struct interior_const_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+template <typename Geometry>
+struct interior_mutable_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+} // namespace traits
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry>
+struct interior_return_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename Polygon>
+struct interior_return_type<polygon_tag, Polygon>
+{
+ typedef typename boost::remove_const<Polygon>::type nc_polygon_type;
+
+ typedef typename mpl::if_
+ <
+ boost::is_const<Polygon>,
+ typename traits::interior_const_type<nc_polygon_type>::type,
+ typename traits::interior_mutable_type<nc_polygon_type>::type
+ >::type type;
+};
+
+
+
+
+template <typename GeometryTag, typename Geometry>
+struct interior_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename Polygon>
+struct interior_type<polygon_tag, Polygon>
+{
+ typedef typename boost::remove_reference
+ <
+ typename interior_return_type<polygon_tag, Polygon>::type
+ >::type type;
+};
+
+
+} // namespace core_dispatch
+#endif
+
+
+/*!
+\brief \brief_meta{type, interior_type (container type
+ of inner rings), \meta_geometry_type}
+\details Interior rings should be organized as a container
+ (std::vector, std::deque, boost::array) with
+ Boost.Range support. This metafunction defines the type
+ of the container.
+\tparam Geometry A type fullfilling the Polygon or MultiPolygon concept.
+\ingroup core
+
+\qbk{[include reference/core/interior_type.qbk]}
+*/
+template <typename Geometry>
+struct interior_type
+{
+ typedef typename core_dispatch::interior_type
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::type type;
+};
+
+template <typename Geometry>
+struct interior_return_type
+{
+ typedef typename core_dispatch::interior_return_type
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_INTERIOR_TYPE_HPP
diff --git a/src/boost/geometry/core/is_areal.hpp b/src/boost/geometry/core/is_areal.hpp
new file mode 100644
index 0000000..5ddfa75
--- /dev/null
+++ b/src/boost/geometry/core/is_areal.hpp
@@ -0,0 +1,60 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_CORE_IS_AREAL_HPP
+#define BOOST_GEOMETRY_CORE_IS_AREAL_HPP
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag> struct is_areal : boost::false_type {};
+
+template <> struct is_areal<ring_tag> : boost::true_type {};
+template <> struct is_areal<box_tag> : boost::true_type {};
+template <> struct is_areal<polygon_tag> : boost::true_type {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+/*!
+ \brief Meta-function defining "true" for areal types (box, (multi)polygon, ring),
+ \note Used for tag dispatching and meta-function finetuning
+ \note Also a "ring" has areal properties within Boost.Geometry
+ \ingroup core
+*/
+template <typename Geometry>
+struct is_areal : core_dispatch::is_areal<typename tag<Geometry>::type>
+{};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_IS_AREAL_HPP
diff --git a/src/boost/geometry/core/mutable_range.hpp b/src/boost/geometry/core/mutable_range.hpp
new file mode 100644
index 0000000..9b53e40
--- /dev/null
+++ b/src/boost/geometry/core/mutable_range.hpp
@@ -0,0 +1,98 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_MUTABLE_RANGE_HPP
+#define BOOST_GEOMETRY_CORE_MUTABLE_RANGE_HPP
+
+
+#include <cstddef>
+
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/range.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace traits
+{
+
+/*!
+\brief Metafunction to define the argument passed to the three
+ traits classes clear, push_back and resize
+\ingroup mutable_range
+ */
+template <typename Range>
+struct rvalue_type
+{
+ typedef typename boost::remove_reference<Range>::type& type;
+};
+
+
+/*!
+\brief Traits class to clear a geometry
+\ingroup mutable_range
+ */
+template <typename Range>
+struct clear
+{
+ static inline void apply(typename rvalue_type<Range>::type range)
+ {
+ range.clear();
+ }
+};
+
+
+/*!
+\brief Traits class to append a point to a range (ring, linestring, multi*)
+\ingroup mutable_range
+ */
+template <typename Range>
+struct push_back
+{
+ typedef typename boost::range_value
+ <
+ typename boost::remove_reference<Range>::type
+ >::type item_type;
+
+ static inline void apply(typename rvalue_type<Range>::type range,
+ item_type const& item)
+ {
+ range.push_back(item);
+ }
+};
+
+
+/*!
+\brief Traits class to append a point to a range (ring, linestring, multi*)
+\ingroup mutable_range
+ */
+template <typename Range>
+struct resize
+{
+ static inline void apply(typename rvalue_type<Range>::type range,
+ std::size_t new_size)
+ {
+ range.resize(new_size);
+ }
+};
+
+
+} // namespace traits
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_MUTABLE_RANGE_HPP
diff --git a/src/boost/geometry/core/point_order.hpp b/src/boost/geometry/core/point_order.hpp
new file mode 100644
index 0000000..f09086a
--- /dev/null
+++ b/src/boost/geometry/core/point_order.hpp
@@ -0,0 +1,162 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_POINT_ORDER_HPP
+#define BOOST_GEOMETRY_CORE_POINT_ORDER_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Enumerates options for the order of points within polygons
+\ingroup enum
+\details The enumeration order_selector describes options for the order of
+ points within a polygon. Polygons can be ordered either clockwise or
+ counterclockwise. The specific order of a polygon type is defined by the
+ point_order metafunction. The point_order metafunction defines a value,
+ which is one of the values enumerated in the order_selector
+
+\qbk{
+[heading See also]
+[link geometry.reference.core.point_order The point_order metafunction]
+}
+*/
+enum order_selector
+{
+ /// Points are ordered clockwise
+ clockwise = 1,
+ /// Points are ordered counter clockwise
+ counterclockwise = 2,
+ /// Points might be stored in any order, algorithms will determine it on the
+ /// fly (not yet supported)
+ order_undetermined = 0
+};
+
+namespace traits
+{
+
+/*!
+\brief Traits class indicating the order of contained points within a
+ ring or (multi)polygon, clockwise, counter clockwise or not known.
+\ingroup traits
+\tparam Ring ring
+*/
+template <typename Ring>
+struct point_order
+{
+ static const order_selector value = clockwise;
+};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace point_order
+{
+
+struct clockwise
+{
+ static const order_selector value = geometry::clockwise;
+};
+
+
+}} // namespace detail::point_order
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct point_order
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+template <typename Point>
+struct point_order<point_tag, Point>
+ : public detail::point_order::clockwise {};
+
+template <typename Segment>
+struct point_order<segment_tag, Segment>
+ : public detail::point_order::clockwise {};
+
+
+template <typename Box>
+struct point_order<box_tag, Box>
+ : public detail::point_order::clockwise {};
+
+template <typename LineString>
+struct point_order<linestring_tag, LineString>
+ : public detail::point_order::clockwise {};
+
+
+template <typename Ring>
+struct point_order<ring_tag, Ring>
+{
+ static const order_selector value
+ = geometry::traits::point_order<Ring>::value;
+};
+
+// Specialization for polygon: the order is the order of its rings
+template <typename Polygon>
+struct point_order<polygon_tag, Polygon>
+{
+ static const order_selector value = core_dispatch::point_order
+ <
+ ring_tag,
+ typename ring_type<polygon_tag, Polygon>::type
+ >::value ;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_meta{value, point order (clockwise\, counterclockwise),
+ \meta_geometry_type}
+\tparam Geometry \tparam_geometry
+\ingroup core
+
+\qbk{[include reference/core/point_order.qbk]}
+*/
+template <typename Geometry>
+struct point_order
+{
+ static const order_selector value = core_dispatch::point_order
+ <
+ typename tag<Geometry>::type,
+ typename boost::remove_const<Geometry>::type
+ >::value;
+};
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_POINT_ORDER_HPP
diff --git a/src/boost/geometry/core/point_type.hpp b/src/boost/geometry/core/point_type.hpp
new file mode 100644
index 0000000..f49a43c
--- /dev/null
+++ b/src/boost/geometry/core/point_type.hpp
@@ -0,0 +1,130 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_POINT_TYPE_HPP
+#define BOOST_GEOMETRY_CORE_POINT_TYPE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+/*!
+\brief Traits class indicating the type of contained points
+\ingroup traits
+\par Geometries:
+ - all geometries except point
+\par Specializations should provide:
+ - typedef P type (where P should fulfil the Point concept)
+\tparam Geometry geometry
+*/
+template <typename Geometry>
+struct point_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Geometry>)
+ );
+};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct point_type
+{
+ // Default: call traits to get point type
+ typedef typename boost::remove_const
+ <
+ typename traits::point_type<Geometry>::type
+ >::type type;
+};
+
+
+// Specialization for point: the point itself
+template <typename Point>
+struct point_type<point_tag, Point>
+{
+ typedef Point type;
+};
+
+
+// Specializations for linestring/ring, via boost::range
+template <typename Linestring>
+struct point_type<linestring_tag, Linestring>
+{
+ typedef typename boost::range_value<Linestring>::type type;
+};
+
+
+template <typename Ring>
+struct point_type<ring_tag, Ring>
+{
+ typedef typename boost::range_value<Ring>::type type;
+};
+
+
+// Specialization for polygon: the point-type is the point-type of its rings
+template <typename Polygon>
+struct point_type<polygon_tag, Polygon>
+{
+ typedef typename point_type
+ <
+ ring_tag,
+ typename ring_type<polygon_tag, Polygon>::type
+ >::type type;
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_meta{type, point_type, \meta_geometry_type}
+\tparam Geometry \tparam_geometry
+\ingroup core
+
+\qbk{[include reference/core/point_type.qbk]}
+*/
+template <typename Geometry>
+struct point_type
+{
+ typedef typename boost::remove_const<Geometry>::type ncg;
+ typedef typename core_dispatch::point_type
+ <
+ typename tag<Geometry>::type,
+ ncg
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_POINT_TYPE_HPP
diff --git a/src/boost/geometry/core/radian_access.hpp b/src/boost/geometry/core/radian_access.hpp
new file mode 100644
index 0000000..bac77d7
--- /dev/null
+++ b/src/boost/geometry/core/radian_access.hpp
@@ -0,0 +1,152 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_CORE_RADIAN_ACCESS_HPP
+#define BOOST_GEOMETRY_CORE_RADIAN_ACCESS_HPP
+
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+
+#include <boost/geometry/util/math.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template<std::size_t Dimension, typename Geometry>
+struct degree_radian_converter
+{
+ typedef typename fp_coordinate_type<Geometry>::type coordinate_type;
+
+ static inline coordinate_type get(Geometry const& geometry)
+ {
+ return boost::numeric_cast
+ <
+ coordinate_type
+ >(geometry::get<Dimension>(geometry) * geometry::math::d2r);
+ }
+
+ static inline void set(Geometry& geometry, coordinate_type const& radians)
+ {
+ geometry::set<Dimension>(geometry, boost::numeric_cast
+ <
+ coordinate_type
+ >(radians * geometry::math::r2d));
+ }
+
+};
+
+
+// Default, radian (or any other coordinate system) just works like "get"
+template <std::size_t Dimension, typename Geometry, typename DegreeOrRadian>
+struct radian_access
+{
+ typedef typename fp_coordinate_type<Geometry>::type coordinate_type;
+
+ static inline coordinate_type get(Geometry const& geometry)
+ {
+ return geometry::get<Dimension>(geometry);
+ }
+
+ static inline void set(Geometry& geometry, coordinate_type const& radians)
+ {
+ geometry::set<Dimension>(geometry, radians);
+ }
+};
+
+// Specialize, any "degree" coordinate system will be converted to radian
+// but only for dimension 0,1 (so: dimension 2 and heigher are untouched)
+
+template
+<
+ typename Geometry,
+ template<typename> class CoordinateSystem
+>
+struct radian_access<0, Geometry, CoordinateSystem<degree> >
+ : degree_radian_converter<0, Geometry>
+{};
+
+
+template
+<
+ typename Geometry,
+ template<typename> class CoordinateSystem
+>
+struct radian_access<1, Geometry, CoordinateSystem<degree> >
+ : degree_radian_converter<1, Geometry>
+{};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief get coordinate value of a point, result is in Radian
+\details Result is in Radian, even if source coordinate system
+ is in Degrees
+\return coordinate value
+\ingroup get
+\tparam Dimension dimension
+\tparam Geometry geometry
+\param geometry geometry to get coordinate value from
+\note Only applicable to coordinate systems templatized by units,
+ e.g. spherical or geographic coordinate systems
+*/
+template <std::size_t Dimension, typename Geometry>
+inline typename fp_coordinate_type<Geometry>::type get_as_radian(Geometry const& geometry)
+{
+ return detail::radian_access<Dimension, Geometry,
+ typename coordinate_system<Geometry>::type>::get(geometry);
+}
+
+
+/*!
+\brief set coordinate value (in radian) to a point
+\details Coordinate value will be set correctly, if coordinate system of
+ point is in Degree, Radian value will be converted to Degree
+\ingroup set
+\tparam Dimension dimension
+\tparam Geometry geometry
+\param geometry geometry to assign coordinate to
+\param radians coordinate value to assign
+\note Only applicable to coordinate systems templatized by units,
+ e.g. spherical or geographic coordinate systems
+*/
+template <std::size_t Dimension, typename Geometry>
+inline void set_from_radian(Geometry& geometry,
+ typename fp_coordinate_type<Geometry>::type const& radians)
+{
+ detail::radian_access<Dimension, Geometry,
+ typename coordinate_system<Geometry>::type>::set(geometry, radians);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_RADIAN_ACCESS_HPP
diff --git a/src/boost/geometry/core/reverse_dispatch.hpp b/src/boost/geometry/core/reverse_dispatch.hpp
new file mode 100644
index 0000000..2e4fb80
--- /dev/null
+++ b/src/boost/geometry/core/reverse_dispatch.hpp
@@ -0,0 +1,67 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_CORE_REVERSE_DISPATCH_HPP
+#define BOOST_GEOMETRY_CORE_REVERSE_DISPATCH_HPP
+
+
+#include <cstddef>
+
+#include <boost/type_traits.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/greater.hpp>
+
+#include <boost/geometry/core/geometry_id.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Different geometries: reverse_dispatch if second ID < first ID
+template <std::size_t GeometryId1, std::size_t GeometryId2>
+struct reverse_dispatch : boost::mpl::if_c
+ <
+ (GeometryId1 > GeometryId2),
+ boost::true_type,
+ boost::false_type
+ >
+{};
+
+
+// Same geometry: never reverse_dispatch
+template <std::size_t GeometryId>
+struct reverse_dispatch<GeometryId, GeometryId> : boost::false_type {};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+template <typename Geometry1, typename Geometry2>
+struct reverse_dispatch : detail::reverse_dispatch
+ <
+ geometry_id<Geometry1>::type::value,
+ geometry_id<Geometry2>::type::value
+ >
+{};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_REVERSE_DISPATCH_HPP
diff --git a/src/boost/geometry/core/ring_type.hpp b/src/boost/geometry/core/ring_type.hpp
new file mode 100644
index 0000000..9b984fa
--- /dev/null
+++ b/src/boost/geometry/core/ring_type.hpp
@@ -0,0 +1,170 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_CORE_RING_TYPE_HPP
+#define BOOST_GEOMETRY_CORE_RING_TYPE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+
+/*!
+\brief Traits class to indicate ring-type of a polygon's exterior ring/interior rings
+\ingroup traits
+\par Geometries:
+ - polygon
+\par Specializations should provide:
+ - typedef XXX type ( e.g. ring<P> )
+\tparam Geometry geometry
+*/
+template <typename Geometry>
+struct ring_const_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+template <typename Geometry>
+struct ring_mutable_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag, typename Geometry>
+struct ring_return_type
+{};
+
+
+template <typename LineString>
+struct ring_return_type<linestring_tag, LineString>
+{
+ typedef LineString& type;
+};
+
+
+template <typename Ring>
+struct ring_return_type<ring_tag, Ring>
+{
+ typedef Ring& type;
+};
+
+
+template <typename Polygon>
+struct ring_return_type<polygon_tag, Polygon>
+{
+ typedef typename boost::remove_const<Polygon>::type nc_polygon_type;
+
+ typedef typename mpl::if_
+ <
+ boost::is_const<Polygon>,
+ typename traits::ring_const_type<nc_polygon_type>::type,
+ typename traits::ring_mutable_type<nc_polygon_type>::type
+ >::type type;
+};
+
+
+template <typename GeometryTag, typename Geometry>
+struct ring_type
+{};
+
+
+template <typename Ring>
+struct ring_type<ring_tag, Ring>
+{
+ typedef Ring type;
+};
+
+
+template <typename Polygon>
+struct ring_type<polygon_tag, Polygon>
+{
+ typedef typename boost::remove_reference
+ <
+ typename ring_return_type<polygon_tag, Polygon>::type
+ >::type type;
+};
+
+
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+/*!
+\brief \brief_meta{type, ring_type, \meta_geometry_type}
+\details A polygon contains one exterior ring
+ and zero or more interior rings (holes).
+ This metafunction retrieves the type of the rings.
+ Exterior ring and each of the interior rings all have the same ring_type.
+\tparam Geometry A type fullfilling the Ring, Polygon or MultiPolygon concept.
+\ingroup core
+
+\qbk{[include reference/core/ring_type.qbk]}
+*/
+template <typename Geometry>
+struct ring_type
+{
+ typedef typename core_dispatch::ring_type
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::type type;
+};
+
+
+template <typename Geometry>
+struct ring_return_type
+{
+ typedef typename core_dispatch::ring_return_type
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_RING_TYPE_HPP
diff --git a/src/boost/geometry/core/tag.hpp b/src/boost/geometry/core/tag.hpp
new file mode 100644
index 0000000..5a99c97
--- /dev/null
+++ b/src/boost/geometry/core/tag.hpp
@@ -0,0 +1,70 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_TAG_HPP
+#define BOOST_GEOMETRY_CORE_TAG_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+/*!
+\brief Traits class to attach a tag to a geometry
+\details All geometries should implement a traits::tag<G>::type metafunction to indicate their
+ own geometry type.
+\ingroup traits
+\par Geometries:
+ - all geometries
+\par Specializations should provide:
+ - typedef XXX_tag type; (point_tag, box_tag, ...)
+\tparam Geometry geometry
+*/
+template <typename Geometry, typename Enable = void>
+struct tag
+{
+ typedef void type;
+};
+
+} // namespace traits
+
+
+/*!
+\brief \brief_meta{type, tag, \meta_geometry_type}
+\details With Boost.Geometry, tags are the driving force of the tag dispatching
+ mechanism. The tag metafunction is therefore used in every free function.
+\tparam Geometry \tparam_geometry
+\ingroup core
+
+\qbk{[include reference/core/tag.qbk]}
+*/
+template <typename Geometry>
+struct tag
+{
+ typedef typename traits::tag
+ <
+ typename boost::remove_const<Geometry>::type
+ >::type type;
+};
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_TAG_HPP
diff --git a/src/boost/geometry/core/tag_cast.hpp b/src/boost/geometry/core/tag_cast.hpp
new file mode 100644
index 0000000..47a2e83
--- /dev/null
+++ b/src/boost/geometry/core/tag_cast.hpp
@@ -0,0 +1,84 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_TAG_CAST_HPP
+#define BOOST_GEOMETRY_CORE_TAG_CAST_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Metafunction defining a type being either the specified tag, or one
+ of the specified basetags if the type inherits from them.
+\details Tags can inherit each other. A multi_point inherits, for example,
+ both the multi_tag and the pointlike tag. Often behaviour can be shared
+ between different geometry types. A tag, found by the metafunction tag,
+ can be casted to a more basic tag, and then dispatched by that tag.
+\ingroup core
+\tparam Tag The tag to be casted to one of the base tags
+\tparam BaseTag First base tag
+\tparam BaseTag2 Optional second base tag
+\tparam BaseTag3 Optional third base tag
+\tparam BaseTag4 Optional fourth base tag
+\tparam BaseTag5 Optional fifth base tag
+\tparam BaseTag6 Optional sixth base tag
+\tparam BaseTag7 Optional seventh base tag
+
+\qbk{[include reference/core/tag_cast.qbk]}
+*/
+template
+<
+ typename Tag,
+ typename BaseTag,
+ typename BaseTag2 = void,
+ typename BaseTag3 = void,
+ typename BaseTag4 = void,
+ typename BaseTag5 = void,
+ typename BaseTag6 = void,
+ typename BaseTag7 = void
+>
+struct tag_cast
+{
+ typedef typename boost::mpl::if_
+ <
+ typename boost::is_base_of<BaseTag, Tag>::type,
+ BaseTag,
+ // Try next one in line:
+ typename tag_cast
+ <
+ Tag, BaseTag2, BaseTag3, BaseTag4,
+ BaseTag5, BaseTag6, BaseTag7, void
+ >::type
+ >::type type;
+};
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+// Specialization for last one
+template <typename Tag>
+struct tag_cast<Tag, void, void, void, void, void, void, void>
+{
+ // If not found, take specified tag, so do not cast
+ typedef Tag type;
+};
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_TAG_CAST_HPP
diff --git a/src/boost/geometry/core/tags.hpp b/src/boost/geometry/core/tags.hpp
new file mode 100644
index 0000000..9272858
--- /dev/null
+++ b/src/boost/geometry/core/tags.hpp
@@ -0,0 +1,94 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_CORE_TAGS_HPP
+#define BOOST_GEOMETRY_CORE_TAGS_HPP
+
+
+namespace boost { namespace geometry
+{
+
+// Tags defining strategies linked to coordinate systems
+
+/// Tag used for casting spherical/geographic coordinate systems
+struct spherical_tag {};
+
+
+/// Tag indicating Cartesian coordinate system family (cartesian,epsg)
+struct cartesian_tag {};
+
+/// Tag indicating Spherical polar coordinate system family
+struct spherical_polar_tag : spherical_tag {};
+
+/// Tag indicating Spherical equatorial coordinate system family
+struct spherical_equatorial_tag : spherical_tag {};
+
+/// Tag indicating Geographic coordinate system family (geographic)
+struct geographic_tag : spherical_tag {};
+
+
+
+// Tags defining tag hierarchy
+
+/// For single-geometries (point, linestring, polygon, box, ring, segment)
+struct single_tag {};
+
+
+/// For multiple-geometries (multi_point, multi_linestring, multi_polygon)
+struct multi_tag {};
+
+/// For point-like types (point, multi_point)
+struct pointlike_tag {};
+
+/// For linear types (linestring, multi-linestring, segment)
+struct linear_tag {};
+
+/// For areal types (polygon, multi_polygon, box, ring)
+struct areal_tag {};
+
+// Subset of areal types (polygon, multi_polygon, ring)
+struct polygonal_tag : areal_tag {};
+
+/// For volume types (also box (?), polyhedron)
+struct volumetric_tag {};
+
+
+// Tags defining geometry types
+
+
+/// "default" tag
+struct geometry_not_recognized_tag {};
+
+/// OGC Point identifying tag
+struct point_tag : single_tag, pointlike_tag {};
+
+/// OGC Linestring identifying tag
+struct linestring_tag : single_tag, linear_tag {};
+
+/// OGC Polygon identifying tag
+struct polygon_tag : single_tag, polygonal_tag {};
+
+/// Convenience (linear) ring identifying tag
+struct ring_tag : single_tag, polygonal_tag {};
+
+/// Convenience 2D or 3D box (mbr / aabb) identifying tag
+struct box_tag : single_tag, areal_tag {};
+
+/// Convenience segment (2-points) identifying tag
+struct segment_tag : single_tag, linear_tag {};
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_CORE_TAGS_HPP
diff --git a/src/boost/geometry/core/topological_dimension.hpp b/src/boost/geometry/core/topological_dimension.hpp
new file mode 100644
index 0000000..02f1ed3
--- /dev/null
+++ b/src/boost/geometry/core/topological_dimension.hpp
@@ -0,0 +1,88 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_CORE_TOPOLOGICAL_DIMENSION_HPP
+#define BOOST_GEOMETRY_CORE_TOPOLOGICAL_DIMENSION_HPP
+
+
+#include <boost/mpl/int.hpp>
+
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename GeometryTag>
+struct top_dim {};
+
+
+template <>
+struct top_dim<point_tag> : boost::mpl::int_<0> {};
+
+
+template <>
+struct top_dim<linestring_tag> : boost::mpl::int_<1> {};
+
+
+template <>
+struct top_dim<segment_tag> : boost::mpl::int_<1> {};
+
+
+// ring: topological dimension of two, but some people say: 1 !!
+template <>
+struct top_dim<ring_tag> : boost::mpl::int_<2> {};
+
+
+template <>
+struct top_dim<box_tag> : boost::mpl::int_<2> {};
+
+
+template <>
+struct top_dim<polygon_tag> : boost::mpl::int_<2> {};
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+
+/*!
+ \brief Meta-function returning the topological dimension of a geometry
+ \details The topological dimension defines a point as 0-dimensional,
+ a linestring as 1-dimensional,
+ and a ring or polygon as 2-dimensional.
+ \see http://www.math.okstate.edu/mathdept/dynamics/lecnotes/node36.html
+ \ingroup core
+*/
+template <typename Geometry>
+struct topological_dimension
+ : core_dispatch::top_dim<typename tag<Geometry>::type> {};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_CORE_TOPOLOGICAL_DIMENSION_HPP
diff --git a/src/boost/geometry/domains/gis/io/io.hpp b/src/boost/geometry/domains/gis/io/io.hpp
new file mode 100644
index 0000000..39703e3
--- /dev/null
+++ b/src/boost/geometry/domains/gis/io/io.hpp
@@ -0,0 +1,65 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_HPP
+
+
+#include <boost/geometry/domains/gis/io/wkt/read_wkt.hpp>
+#include <boost/geometry/domains/gis/io/wkt/write_wkt.hpp>
+
+#include <boost/geometry/domains/gis/io/wkt/read_wkt_multi.hpp>
+#include <boost/geometry/domains/gis/io/wkt/write_wkt_multi.hpp>
+
+namespace boost { namespace geometry
+{
+
+struct format_wkt {};
+struct format_wkb {};
+struct format_dsv {};
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct read
+{
+};
+
+template <typename Geometry>
+struct read<format_wkt, Geometry>
+{
+ static inline void apply(Geometry& geometry, std::string const& wkt)
+ {
+ read_wkt<typename tag<Geometry>::type, Geometry>::apply(wkt, geometry);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+template <typename Format, typename Geometry>
+inline void read(Geometry& geometry, std::string const& wkt)
+{
+ geometry::concept::check<Geometry>();
+ dispatch::read<Format, Geometry>::apply(geometry, wkt);
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_HPP
diff --git a/src/boost/geometry/domains/gis/io/wkt/detail/wkt.hpp b/src/boost/geometry/domains/gis/io/wkt/detail/wkt.hpp
new file mode 100644
index 0000000..576a168
--- /dev/null
+++ b/src/boost/geometry/domains/gis/io/wkt/detail/wkt.hpp
@@ -0,0 +1,49 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_HPP
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+
+struct prefix_point
+{
+ static inline const char* apply() { return "POINT"; }
+};
+
+struct prefix_polygon
+{
+ static inline const char* apply() { return "POLYGON"; }
+};
+
+struct prefix_linestring
+{
+ static inline const char* apply() { return "LINESTRING"; }
+};
+
+
+
+}} // namespace wkt::impl
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_HPP
diff --git a/src/boost/geometry/domains/gis/io/wkt/detail/wkt_multi.hpp b/src/boost/geometry/domains/gis/io/wkt/detail/wkt_multi.hpp
new file mode 100644
index 0000000..abfbd28
--- /dev/null
+++ b/src/boost/geometry/domains/gis/io/wkt/detail/wkt_multi.hpp
@@ -0,0 +1,56 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
+
+
+#include <boost/geometry/domains/gis/io/wkt/write_wkt.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+struct prefix_null
+{
+ static inline const char* apply() { return ""; }
+};
+
+struct prefix_multipoint
+{
+ static inline const char* apply() { return "MULTIPOINT"; }
+};
+
+struct prefix_multilinestring
+{
+ static inline const char* apply() { return "MULTILINESTRING"; }
+};
+
+struct prefix_multipolygon
+{
+ static inline const char* apply() { return "MULTIPOLYGON"; }
+};
+
+
+
+}} // namespace wkt::impl
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
diff --git a/src/boost/geometry/domains/gis/io/wkt/read_wkt.hpp b/src/boost/geometry/domains/gis/io/wkt/read_wkt.hpp
new file mode 100644
index 0000000..bc534a2
--- /dev/null
+++ b/src/boost/geometry/domains/gis/io/wkt/read_wkt.hpp
@@ -0,0 +1,692 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_READ_WKT_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_READ_WKT_HPP
+
+#include <string>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/tokenizer.hpp>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/append.hpp>
+#include <boost/geometry/algorithms/clear.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/exception.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/geometry_id.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/coordinate_cast.hpp>
+
+#include <boost/geometry/domains/gis/io/wkt/detail/wkt.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+
+/*!
+\brief Exception showing things wrong with WKT parsing
+\ingroup wkt
+*/
+struct read_wkt_exception : public geometry::exception
+{
+ template <typename Iterator>
+ read_wkt_exception(std::string const& msg,
+ Iterator const& it, Iterator const& end, std::string const& wkt)
+ : message(msg)
+ , wkt(wkt)
+ {
+ if (it != end)
+ {
+ source = " at '";
+ source += it->c_str();
+ source += "'";
+ }
+ complete = message + source + " in '" + wkt.substr(0, 100) + "'";
+ }
+
+ read_wkt_exception(std::string const& msg, std::string const& wkt)
+ : message(msg)
+ , wkt(wkt)
+ {
+ complete = message + "' in (" + wkt.substr(0, 100) + ")";
+ }
+
+ virtual ~read_wkt_exception() throw() {}
+
+ virtual const char* what() const throw()
+ {
+ return complete.c_str();
+ }
+private :
+ std::string source;
+ std::string message;
+ std::string wkt;
+ std::string complete;
+};
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+// (wkt: Well Known Text, defined by OGC for all geometries and implemented by e.g. databases (MySQL, PostGIS))
+namespace detail { namespace wkt {
+
+typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+
+template <typename Point, std::size_t Dimension, std::size_t DimensionCount>
+struct parsing_assigner
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ Point& point, std::string const& wkt)
+ {
+ typedef typename coordinate_type<Point>::type coordinate_type;
+
+ // Stop at end of tokens, or at "," ot ")"
+ bool finished = (it == end || *it == "," || *it == ")");
+
+ try
+ {
+ // Initialize missing coordinates to default constructor (zero)
+ // OR
+ // Use lexical_cast for conversion to double/int
+ // Note that it is much slower than atof. However, it is more standard
+ // and in parsing the change in performance falls probably away against
+ // the tokenizing
+ set<Dimension>(point, finished
+ ? coordinate_type()
+ : coordinate_cast<coordinate_type>::apply(*it));
+ }
+ catch(boost::bad_lexical_cast const& blc)
+ {
+ throw read_wkt_exception(blc.what(), it, end, wkt);
+ }
+ catch(std::exception const& e)
+ {
+ throw read_wkt_exception(e.what(), it, end, wkt);
+ }
+ catch(...)
+ {
+ throw read_wkt_exception("", it, end, wkt);
+ }
+
+ parsing_assigner<Point, Dimension + 1, DimensionCount>::apply(
+ (finished ? it : ++it), end, point, wkt);
+ }
+};
+
+template <typename Point, std::size_t DimensionCount>
+struct parsing_assigner<Point, DimensionCount, DimensionCount>
+{
+ static inline void apply(tokenizer::iterator&, tokenizer::iterator, Point&,
+ std::string const&)
+ {
+ }
+};
+
+
+
+template <typename Iterator>
+inline void handle_open_parenthesis(Iterator& it,
+ Iterator const& end, std::string const& wkt)
+{
+ if (it == end || *it != "(")
+ {
+ throw read_wkt_exception("Expected '('", it, end, wkt);
+ }
+ ++it;
+}
+
+
+template <typename Iterator>
+inline void handle_close_parenthesis(Iterator& it,
+ Iterator const& end, std::string const& wkt)
+{
+ if (it != end && *it == ")")
+ {
+ ++it;
+ }
+ else
+ {
+ throw read_wkt_exception("Expected ')'", it, end, wkt);
+ }
+}
+
+template <typename Iterator>
+inline void check_end(Iterator& it,
+ Iterator const& end, std::string const& wkt)
+{
+ if (it != end)
+ {
+ throw read_wkt_exception("Too much tokens", it, end, wkt);
+ }
+}
+
+/*!
+\brief Internal, parses coordinate sequences, strings are formated like "(1 2,3 4,...)"
+\param it token-iterator, should be pre-positioned at "(", is post-positions after last ")"
+\param end end-token-iterator
+\param out Output itererator receiving coordinates
+*/
+template <typename Point>
+struct container_inserter
+{
+ // Version with output iterator
+ template <typename OutputIterator>
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, OutputIterator out)
+ {
+ handle_open_parenthesis(it, end, wkt);
+
+ Point point;
+
+ // Parse points until closing parenthesis
+
+ while (it != end && *it != ")")
+ {
+ parsing_assigner
+ <
+ Point,
+ 0,
+ dimension<Point>::value
+ >::apply(it, end, point, wkt);
+ out = point;
+ ++out;
+ if (it != end && *it == ",")
+ {
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+
+// Geometry is a value-type or reference-type
+template <typename Geometry>
+struct container_appender
+{
+ typedef typename geometry::point_type
+ <
+ typename boost::remove_reference<Geometry>::type
+ >::type point_type;
+
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, Geometry out)
+ {
+ handle_open_parenthesis(it, end, wkt);
+
+ point_type point;
+
+ // Parse points until closing parenthesis
+
+ while (it != end && *it != ")")
+ {
+ parsing_assigner
+ <
+ point_type,
+ 0,
+ dimension<point_type>::value
+ >::apply(it, end, point, wkt);
+
+ geometry::append(out, point);
+ if (it != end && *it == ",")
+ {
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+/*!
+\brief Internal, parses a point from a string like this "(x y)"
+\note used for parsing points and multi-points
+*/
+template <typename P>
+struct point_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, P& point)
+ {
+ handle_open_parenthesis(it, end, wkt);
+ parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+
+template <typename Geometry>
+struct linestring_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, Geometry& geometry)
+ {
+ container_appender<Geometry&>::apply(it, end, wkt, geometry);
+ }
+};
+
+
+template <typename Ring>
+struct ring_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, Ring& ring)
+ {
+ // A ring should look like polygon((x y,x y,x y...))
+ // So handle the extra opening/closing parentheses
+ // and in between parse using the container-inserter
+ handle_open_parenthesis(it, end, wkt);
+ container_appender<Ring&>::apply(it, end, wkt, ring);
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+
+
+
+/*!
+\brief Internal, parses a polygon from a string like this "((x y,x y),(x y,x y))"
+\note used for parsing polygons and multi-polygons
+*/
+template <typename Polygon>
+struct polygon_parser
+{
+ typedef typename ring_return_type<Polygon>::type ring_return_type;
+ typedef container_appender<ring_return_type> appender;
+
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, Polygon& poly)
+ {
+
+ handle_open_parenthesis(it, end, wkt);
+
+ int n = -1;
+
+ // Stop at ")"
+ while (it != end && *it != ")")
+ {
+ // Parse ring
+ if (++n == 0)
+ {
+ appender::apply(it, end, wkt, exterior_ring(poly));
+ }
+ else
+ {
+ typename ring_type<Polygon>::type ring;
+ appender::apply(it, end, wkt, ring);
+ traits::push_back
+ <
+ typename boost::remove_reference
+ <
+ typename traits::interior_mutable_type<Polygon>::type
+ >::type
+ >::apply(interior_rings(poly), ring);
+ }
+
+ if (it != end && *it == ",")
+ {
+ // Skip "," after ring is parsed
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+inline bool one_of(tokenizer::iterator const& it, std::string const& value,
+ bool& is_present)
+{
+ if (boost::iequals(*it, value))
+ {
+ is_present = true;
+ return true;
+ }
+ return false;
+}
+
+inline bool one_of(tokenizer::iterator const& it, std::string const& value,
+ bool& present1, bool& present2)
+{
+ if (boost::iequals(*it, value))
+ {
+ present1 = true;
+ present2 = true;
+ return true;
+ }
+ return false;
+}
+
+
+inline void handle_empty_z_m(tokenizer::iterator& it, tokenizer::iterator end,
+ bool& has_empty, bool& has_z, bool& has_m)
+{
+ has_empty = false;
+ has_z = false;
+ has_m = false;
+
+ // WKT can optionally have Z and M (measured) values as in
+ // POINT ZM (1 1 5 60), POINT M (1 1 80), POINT Z (1 1 5)
+ // GGL supports any of them as coordinate values, but is not aware
+ // of any Measured value.
+ while (it != end
+ && (one_of(it, "M", has_m)
+ || one_of(it, "Z", has_z)
+ || one_of(it, "EMPTY", has_empty)
+ || one_of(it, "MZ", has_m, has_z)
+ || one_of(it, "ZM", has_z, has_m)
+ )
+ )
+ {
+ ++it;
+ }
+}
+
+/*!
+\brief Internal, starts parsing
+\param tokens boost tokens, parsed with separator " " and keeping separator "()"
+\param geometry string to compare with first token
+*/
+template <typename Geometry>
+inline bool initialize(tokenizer const& tokens,
+ std::string const& geometry_name, std::string const& wkt,
+ tokenizer::iterator& it)
+{
+ it = tokens.begin();
+ if (it != tokens.end() && boost::iequals(*it++, geometry_name))
+ {
+ bool has_empty, has_z, has_m;
+
+ handle_empty_z_m(it, tokens.end(), has_empty, has_z, has_m);
+
+ if (has_z && dimension<Geometry>::type::value < 3)
+ {
+ throw read_wkt_exception("Z only allowed for 3 or more dimensions", wkt);
+ }
+ if (has_empty)
+ {
+ check_end(it, tokens.end(), wkt);
+ return false;
+ }
+ // M is ignored at all.
+
+ return true;
+ }
+ throw read_wkt_exception(std::string("Should start with '") + geometry_name + "'", wkt);
+}
+
+
+template <typename Geometry, template<typename> class Parser, typename PrefixPolicy>
+struct geometry_parser
+{
+ static inline void apply(std::string const& wkt, Geometry& geometry)
+ {
+ geometry::clear(geometry);
+
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it;
+ if (initialize<Geometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ {
+ Parser<Geometry>::apply(it, tokens.end(), wkt, geometry);
+ check_end(it, tokens.end(), wkt);
+ }
+ }
+};
+
+
+
+
+
+/*!
+\brief Supports box parsing
+\note OGC does not define the box geometry, and WKT does not support boxes.
+ However, to be generic GGL supports reading and writing from and to boxes.
+ Boxes are outputted as a standard POLYGON. GGL can read boxes from
+ a standard POLYGON, from a POLYGON with 2 points of from a BOX
+\tparam Box the box
+*/
+template <typename Box>
+struct box_parser
+{
+ static inline void apply(std::string const& wkt, Box& box)
+ {
+ bool should_close = false;
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it = tokens.begin();
+ tokenizer::iterator end = tokens.end();
+ if (it != end && boost::iequals(*it, "POLYGON"))
+ {
+ ++it;
+ bool has_empty, has_z, has_m;
+ handle_empty_z_m(it, end, has_empty, has_z, has_m);
+ if (has_empty)
+ {
+ assign_zero(box);
+ return;
+ }
+ handle_open_parenthesis(it, end, wkt);
+ should_close = true;
+ }
+ else if (it != end && boost::iequals(*it, "BOX"))
+ {
+ ++it;
+ }
+ else
+ {
+ throw read_wkt_exception("Should start with 'POLYGON' or 'BOX'", wkt);
+ }
+
+ typedef typename point_type<Box>::type point_type;
+ std::vector<point_type> points;
+ container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
+
+ if (should_close)
+ {
+ handle_close_parenthesis(it, end, wkt);
+ }
+ check_end(it, end, wkt);
+
+ int index = 0;
+ int n = boost::size(points);
+ if (n == 2)
+ {
+ index = 1;
+ }
+ else if (n == 4 || n == 5)
+ {
+ // In case of 4 or 5 points, we do not check the other ones, just
+ // take the opposite corner which is always 2
+ index = 2;
+ }
+ else
+ {
+ throw read_wkt_exception("Box should have 2,4 or 5 points", wkt);
+ }
+
+ geometry::detail::assign_point_to_index<min_corner>(points.front(), box);
+ geometry::detail::assign_point_to_index<max_corner>(points[index], box);
+ }
+};
+
+
+/*!
+\brief Supports segment parsing
+\note OGC does not define the segment, and WKT does not support segmentes.
+ However, it is useful to implement it, also for testing purposes
+\tparam Segment the segment
+*/
+template <typename Segment>
+struct segment_parser
+{
+ static inline void apply(std::string const& wkt, Segment& segment)
+ {
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it = tokens.begin();
+ tokenizer::iterator end = tokens.end();
+ if (it != end &&
+ (boost::iequals(*it, "SEGMENT")
+ || boost::iequals(*it, "LINESTRING") ))
+ {
+ ++it;
+ }
+ else
+ {
+ throw read_wkt_exception("Should start with 'LINESTRING' or 'SEGMENT'", wkt);
+ }
+
+ typedef typename point_type<Segment>::type point_type;
+ std::vector<point_type> points;
+ container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
+
+ check_end(it, end, wkt);
+
+ if (boost::size(points) == 2)
+ {
+ geometry::detail::assign_point_to_index<0>(points.front(), segment);
+ geometry::detail::assign_point_to_index<1>(points.back(), segment);
+ }
+ else
+ {
+ throw read_wkt_exception("Segment should have 2 points", wkt);
+ }
+
+ }
+};
+
+
+
+}} // namespace detail::wkt
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct read_wkt {};
+
+
+template <typename Point>
+struct read_wkt<point_tag, Point>
+ : detail::wkt::geometry_parser
+ <
+ Point,
+ detail::wkt::point_parser,
+ detail::wkt::prefix_point
+ >
+{};
+
+
+template <typename L>
+struct read_wkt<linestring_tag, L>
+ : detail::wkt::geometry_parser
+ <
+ L,
+ detail::wkt::linestring_parser,
+ detail::wkt::prefix_linestring
+ >
+{};
+
+template <typename Ring>
+struct read_wkt<ring_tag, Ring>
+ : detail::wkt::geometry_parser
+ <
+ Ring,
+ detail::wkt::ring_parser,
+ detail::wkt::prefix_polygon
+ >
+{};
+
+template <typename Geometry>
+struct read_wkt<polygon_tag, Geometry>
+ : detail::wkt::geometry_parser
+ <
+ Geometry,
+ detail::wkt::polygon_parser,
+ detail::wkt::prefix_polygon
+ >
+{};
+
+
+// Box (Non-OGC)
+template <typename Box>
+struct read_wkt<box_tag, Box>
+ : detail::wkt::box_parser<Box>
+{};
+
+// Segment (Non-OGC)
+template <typename Segment>
+struct read_wkt<segment_tag, Segment>
+ : detail::wkt::segment_parser<Segment>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Parses OGC Well-Known Text (\ref WKT) into a geometry (any geometry)
+\ingroup wkt
+\param wkt string containing \ref WKT
+\param geometry output geometry
+\par Example:
+\note It is case insensitive and can have the WKT forms "point", "point m", "point z", "point zm", "point mz"
+\note Empty sequences can have forms as "LINESTRING ()" or "POLYGON(())"
+Small example showing how to use read_wkt to build a point
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_point
+\line {
+\until }
+\par Example:
+Small example showing how to use read_wkt to build a linestring
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_linestring
+\line {
+\until }
+\par Example:
+Small example showing how to use read_wkt to build a polygon
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_polygon
+\line {
+\until }
+*/
+template <typename Geometry>
+inline void read_wkt(std::string const& wkt, Geometry& geometry)
+{
+ geometry::concept::check<Geometry>();
+ dispatch::read_wkt<typename tag<Geometry>::type, Geometry>::apply(wkt, geometry);
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_READ_WKT_HPP
diff --git a/src/boost/geometry/domains/gis/io/wkt/read_wkt_multi.hpp b/src/boost/geometry/domains/gis/io/wkt/read_wkt_multi.hpp
new file mode 100644
index 0000000..379a9fa
--- /dev/null
+++ b/src/boost/geometry/domains/gis/io/wkt/read_wkt_multi.hpp
@@ -0,0 +1,112 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_READ_WKT_MULTI_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_READ_WKT_MULTI_HPP
+
+#include <string>
+
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+
+#include <boost/geometry/domains/gis/io/wkt/read_wkt.hpp>
+#include <boost/geometry/domains/gis/io/wkt/detail/wkt_multi.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace wkt {
+
+template <typename MultiGeometry, template<typename> class Parser, typename PrefixPolicy>
+struct multi_parser
+{
+ static inline void apply(std::string const& wkt, MultiGeometry& geometry)
+ {
+ traits::clear<MultiGeometry>::apply(geometry);
+
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it;
+ if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ {
+ handle_open_parenthesis(it, tokens.end(), wkt);
+
+ // Parse sub-geometries
+ while(it != tokens.end() && *it != ")")
+ {
+ traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
+ Parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, geometry.back());
+ if (it != tokens.end() && *it == ",")
+ {
+ // Skip "," after multi-element is parsed
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, tokens.end(), wkt);
+ }
+ }
+};
+
+
+
+
+}} // namespace detail::wkt
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiGeometry>
+struct read_wkt<multi_point_tag, MultiGeometry>
+ : detail::wkt::multi_parser
+ <
+ MultiGeometry,
+ detail::wkt::point_parser,
+ detail::wkt::prefix_multipoint
+ >
+{};
+
+
+template <typename MultiGeometry>
+struct read_wkt<multi_linestring_tag, MultiGeometry>
+ : detail::wkt::multi_parser
+ <
+ MultiGeometry,
+ detail::wkt::linestring_parser,
+ detail::wkt::prefix_multilinestring
+ >
+{};
+
+
+template <typename MultiGeometry>
+struct read_wkt<multi_polygon_tag, MultiGeometry>
+ : detail::wkt::multi_parser
+ <
+ MultiGeometry,
+ detail::wkt::polygon_parser,
+ detail::wkt::prefix_multipolygon
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_READ_WKT_MULTI_HPP
diff --git a/src/boost/geometry/domains/gis/io/wkt/wkt.hpp b/src/boost/geometry/domains/gis/io/wkt/wkt.hpp
new file mode 100644
index 0000000..420e816
--- /dev/null
+++ b/src/boost/geometry/domains/gis/io/wkt/wkt.hpp
@@ -0,0 +1,25 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WKT_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WKT_HPP
+
+
+#include <boost/geometry/domains/gis/io/wkt/read_wkt.hpp>
+#include <boost/geometry/domains/gis/io/wkt/write_wkt.hpp>
+
+#include <boost/geometry/domains/gis/io/wkt/read_wkt_multi.hpp>
+#include <boost/geometry/domains/gis/io/wkt/write_wkt_multi.hpp>
+
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WKT_HPP
diff --git a/src/boost/geometry/domains/gis/io/wkt/write_wkt.hpp b/src/boost/geometry/domains/gis/io/wkt/write_wkt.hpp
new file mode 100644
index 0000000..7bf52c1
--- /dev/null
+++ b/src/boost/geometry/domains/gis/io/wkt/write_wkt.hpp
@@ -0,0 +1,394 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WRITE_WKT_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WRITE_WKT_HPP
+
+#include <ostream>
+#include <string>
+
+#include <boost/array.hpp>
+#include <boost/concept/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/geometries/ring.hpp>
+
+#include <boost/geometry/domains/gis/io/wkt/detail/wkt.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt
+{
+
+template <typename P, int I, int Count>
+struct stream_coordinate
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os, P const& p)
+ {
+ os << (I > 0 ? " " : "") << get<I>(p);
+ stream_coordinate<P, I + 1, Count>::apply(os, p);
+ }
+};
+
+template <typename P, int Count>
+struct stream_coordinate<P, Count, Count>
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>&, P const&)
+ {}
+};
+
+struct prefix_linestring_par
+{
+ static inline const char* apply() { return "LINESTRING("; }
+};
+
+struct prefix_ring_par_par
+{
+ // Note, double parentheses are intentional, indicating WKT ring begin/end
+ static inline const char* apply() { return "POLYGON(("; }
+};
+
+struct opening_parenthesis
+{
+ static inline const char* apply() { return "("; }
+};
+
+struct closing_parenthesis
+{
+ static inline const char* apply() { return ")"; }
+};
+
+struct double_closing_parenthesis
+{
+ static inline const char* apply() { return "))"; }
+};
+
+
+
+
+/*!
+\brief Stream points as \ref WKT
+*/
+template <typename Point, typename Policy>
+struct wkt_point
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os, Point const& p)
+ {
+ os << Policy::apply() << "(";
+ stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p);
+ os << ")";
+ }
+};
+
+/*!
+\brief Stream ranges as WKT
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename Range, typename PrefixPolicy, typename SuffixPolicy>
+struct wkt_range
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Range const& range)
+ {
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ bool first = true;
+
+ os << PrefixPolicy::apply();
+
+ // TODO: check EMPTY here
+
+ for (iterator_type it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ os << (first ? "" : ",");
+ stream_coordinate
+ <
+ point_type, 0, dimension<point_type>::type::value
+ >::apply(os, *it);
+ first = false;
+ }
+
+ os << SuffixPolicy::apply();
+ }
+
+private:
+ typedef typename boost::range_value<Range>::type point_type;
+};
+
+/*!
+\brief Stream sequence of points as WKT-part, e.g. (1 2),(3 4)
+\note Used in polygon, all multi-geometries
+*/
+
+
+
+template <typename Range>
+struct wkt_sequence
+ : wkt_range
+ <
+ Range,
+ opening_parenthesis,
+ closing_parenthesis
+ >
+{};
+
+
+template <typename Polygon, typename PrefixPolicy>
+struct wkt_poly
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Polygon const& poly)
+ {
+ typedef typename ring_type<Polygon const>::type ring;
+
+ os << PrefixPolicy::apply();
+ // TODO: check EMPTY here
+ os << "(";
+ wkt_sequence<ring>::apply(os, exterior_ring(poly));
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ os << ",";
+ wkt_sequence<ring>::apply(os, *it);
+ }
+ os << ")";
+ }
+};
+
+
+template <typename Box>
+struct wkt_box
+{
+ typedef typename point_type<Box>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Box const& box)
+ {
+ // Convert to ring, then stream
+ typedef model::ring<point_type> ring_type;
+ ring_type ring;
+ geometry::convert(box, ring);
+ os << "POLYGON(";
+ wkt_sequence<ring_type>::apply(os, ring);
+ os << ")";
+ }
+
+ private:
+
+ inline wkt_box()
+ {
+ // Only streaming of boxes with two dimensions is support, otherwise it is a polyhedron!
+ //assert_dimension<B, 2>();
+ }
+};
+
+
+template <typename Segment>
+struct wkt_segment
+{
+ typedef typename point_type<Segment>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Segment const& segment)
+ {
+ // Convert to two points, then stream
+ typedef boost::array<point_type, 2> sequence;
+
+ sequence points;
+ geometry::detail::assign_point_from_index<0>(segment, points[0]);
+ geometry::detail::assign_point_from_index<1>(segment, points[1]);
+
+ // In Boost.Geometry a segment is represented
+ // in WKT-format like (for 2D): LINESTRING(x y,x y)
+ os << "LINESTRING";
+ wkt_sequence<sequence>::apply(os, points);
+ }
+
+ private:
+
+ inline wkt_segment()
+ {}
+};
+
+}} // namespace detail::wkt
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct wkt
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename Point>
+struct wkt<point_tag, Point>
+ : detail::wkt::wkt_point
+ <
+ Point,
+ detail::wkt::prefix_point
+ >
+{};
+
+
+template <typename Linestring>
+struct wkt<linestring_tag, Linestring>
+ : detail::wkt::wkt_range
+ <
+ Linestring,
+ detail::wkt::prefix_linestring_par,
+ detail::wkt::closing_parenthesis
+ >
+{};
+
+
+/*!
+\brief Specialization to stream a box as WKT
+\details A "box" does not exist in WKT.
+It is therefore streamed as a polygon
+*/
+template <typename Box>
+struct wkt<box_tag, Box>
+ : detail::wkt::wkt_box<Box>
+{};
+
+template <typename Segment>
+struct wkt<segment_tag, Segment>
+ : detail::wkt::wkt_segment<Segment>
+{};
+
+
+/*!
+\brief Specialization to stream a ring as WKT
+\details A ring or "linear_ring" does not exist in WKT.
+A ring is equivalent to a polygon without inner rings
+It is therefore streamed as a polygon
+*/
+template <typename Ring>
+struct wkt<ring_tag, Ring>
+ : detail::wkt::wkt_range
+ <
+ Ring,
+ detail::wkt::prefix_ring_par_par,
+ detail::wkt::double_closing_parenthesis
+ >
+{};
+
+
+/*!
+\brief Specialization to stream polygon as WKT
+*/
+template <typename Polygon>
+struct wkt<polygon_tag, Polygon>
+ : detail::wkt::wkt_poly
+ <
+ Polygon,
+ detail::wkt::prefix_polygon
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup wkt
+\details Stream manipulator, streams geometry classes as \ref WKT streams
+\par Example:
+Small example showing how to use the wkt class
+\dontinclude doxygen_1.cpp
+\skip example_as_wkt_point
+\line {
+\until }
+*/
+template <typename Geometry>
+class wkt_manipulator
+{
+public:
+
+ inline wkt_manipulator(Geometry const& g)
+ : m_geometry(g)
+ {}
+
+ template <typename Char, typename Traits>
+ inline friend std::basic_ostream<Char, Traits>& operator<<(
+ std::basic_ostream<Char, Traits>& os,
+ wkt_manipulator const& m)
+ {
+ dispatch::wkt
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(os, m.m_geometry);
+ os.flush();
+ return os;
+ }
+
+private:
+ Geometry const& m_geometry;
+};
+
+/*!
+\brief Main WKT-streaming function
+\ingroup wkt
+\par Example:
+Small example showing how to use the wkt helper function
+\dontinclude doxygen_1.cpp
+\skip example_as_wkt_vector
+\line {
+\until }
+*/
+template <typename Geometry>
+inline wkt_manipulator<Geometry> wkt(Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ return wkt_manipulator<Geometry>(geometry);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WRITE_WKT_HPP
diff --git a/src/boost/geometry/domains/gis/io/wkt/write_wkt_multi.hpp b/src/boost/geometry/domains/gis/io/wkt/write_wkt_multi.hpp
new file mode 100644
index 0000000..f7ee47d
--- /dev/null
+++ b/src/boost/geometry/domains/gis/io/wkt/write_wkt_multi.hpp
@@ -0,0 +1,117 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
+
+
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+#include <boost/geometry/domains/gis/io/wkt/write_wkt.hpp>
+#include <boost/geometry/domains/gis/io/wkt/detail/wkt_multi.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt
+{
+
+
+template <typename Multi, typename StreamPolicy, typename PrefixPolicy>
+struct wkt_multi
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Multi const& geometry)
+ {
+ os << PrefixPolicy::apply();
+ // TODO: check EMPTY here
+ os << "(";
+
+ for (typename boost::range_iterator<Multi const>::type
+ it = boost::begin(geometry);
+ it != boost::end(geometry);
+ ++it)
+ {
+ if (it != boost::begin(geometry))
+ {
+ os << ",";
+ }
+ StreamPolicy::apply(os, *it);
+ }
+
+ os << ")";
+ }
+};
+
+}} // namespace wkt::impl
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Multi>
+struct wkt<multi_point_tag, Multi>
+ : detail::wkt::wkt_multi
+ <
+ Multi,
+ detail::wkt::wkt_point
+ <
+ typename boost::range_value<Multi>::type,
+ detail::wkt::prefix_null
+ >,
+ detail::wkt::prefix_multipoint
+ >
+{};
+
+
+template <typename Multi>
+struct wkt<multi_linestring_tag, Multi>
+ : detail::wkt::wkt_multi
+ <
+ Multi,
+ detail::wkt::wkt_sequence
+ <
+ typename boost::range_value<Multi>::type
+ >,
+ detail::wkt::prefix_multilinestring
+ >
+{};
+
+
+template <typename Multi>
+struct wkt<multi_polygon_tag, Multi>
+ : detail::wkt::wkt_multi
+ <
+ Multi,
+ detail::wkt::wkt_poly
+ <
+ typename boost::range_value<Multi>::type,
+ detail::wkt::prefix_null
+ >,
+ detail::wkt::prefix_multipolygon
+ >
+{};
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/intersecting_inserter.hpp b/src/boost/geometry/extensions/algorithms/buffer/intersecting_inserter.hpp
new file mode 100644
index 0000000..674f689
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/intersecting_inserter.hpp
@@ -0,0 +1,93 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_INTERSECTING_INSERTER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_INTERSECTING_INSERTER_HPP
+
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+template
+<
+ typename Collection // usually collection of rings
+>
+struct intersecting_inserter
+{
+ typedef typename boost::range_value<Collection>::type item_type;
+ typedef typename geometry::ring_type<item_type>::type ring_type;
+ typedef typename geometry::point_type<ring_type>::type point_type;
+
+ intersecting_inserter(Collection& c)
+ : m_collection(c)
+ , m_index(0)
+ {}
+
+ inline void start_ring()
+ {
+ // clear current ring
+ m_ring.clear();
+ m_index = 0;
+ }
+
+ inline ring_type& get_ring()
+ {
+ return m_ring;
+ }
+
+
+ inline void insert(point_type const& point)
+ {
+ m_ring.push_back(point);
+ }
+
+
+ inline void close_and_insert_ring()
+ {
+ if (boost::size(m_ring) > 0)
+ {
+ // Close the ring
+ point_type p = m_ring.front();
+ insert(p);
+
+ item_type poly;
+ poly.outer() = m_ring;
+ m_collection.push_back(poly);
+ }
+ }
+
+
+private :
+ Collection& m_collection;
+ ring_type m_ring;
+ std::size_t m_index;
+};
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_INTERSECTING_INSERTER_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp b/src/boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp
new file mode 100644
index 0000000..d0db8c3
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp
@@ -0,0 +1,84 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINE_LINE_INTERSECTION_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINE_LINE_INTERSECTION_HPP
+
+
+#include <boost/geometry/util/math.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+// TODO: once change this to proper strategy
+// It is different from current segment intersection because these are not segments but lines
+// If we have the Line concept, we can create a strategy
+template <typename Point, typename Line1, typename Line2 = Line1>
+struct line_line_intersection
+{
+ template <typename A, typename B, typename C, typename D>
+ static inline A det(A const& a, B const& b, C const& c, D const& d)
+ {
+ return a * d - b * c;
+ }
+
+ static inline bool apply(Line1 const& line1, Line2 const& line2, Point& p)
+ {
+ // See http://mathworld.wolfram.com/Line-LineIntersection.html
+ typedef typename coordinate_type<Point>::type coordinate_type;
+ coordinate_type x1 = get<0,0>(line1), y1 = get<0,1>(line1);
+ coordinate_type x2 = get<1,0>(line1), y2 = get<1,1>(line1);
+ coordinate_type x3 = get<0,0>(line2), y3 = get<0,1>(line2);
+ coordinate_type x4 = get<1,0>(line2), y4 = get<1,1>(line2);
+
+ coordinate_type denominator = det(x1 - x2, y1 - y2, x3 - x4, y3 - y4);
+
+ // If denominator is zero, segments are parallel.
+ // We have context information, so know that it should then
+ // be the case that line1.p2 == line2.p1, and that is the
+ // intersection point.
+ if (geometry::math::equals(denominator, 0.0))
+ {
+ set<0>(p, x2);
+ set<1>(p, y2);
+ return true;
+ }
+
+ coordinate_type d1 = det(x1, y1, x2, y2);
+ coordinate_type d2 = det(x3, y3, x4, y4);
+ coordinate_type px = det(d1, x1 - x2, d2, x3 - x4) / denominator;
+ coordinate_type py = det(d1, y1 - y2, d2, y3 - y4) / denominator;
+
+ set<0>(p, px);
+ set<1>(p, py);
+
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER
+ if (geometry::math::abs(denominator) < 1.0e-7)
+ {
+ std::cout << "small " << denominator << std::endl;
+ }
+#endif
+ return geometry::math::abs(denominator) > 1.0e-7;
+ }
+};
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINE_LINE_INTERSECTION_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/linestring_buffer.hpp b/src/boost/geometry/extensions/algorithms/buffer/linestring_buffer.hpp
new file mode 100644
index 0000000..5fa08f0
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/linestring_buffer.hpp
@@ -0,0 +1,223 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINESTRING_BUFFER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINESTRING_BUFFER_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+#include <boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/intersecting_inserter.hpp>
+
+#include <boost/geometry/geometries/segment.hpp>
+
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+template
+<
+ typename Linestring,
+ typename Polygon,
+ typename DistanceStrategy,
+ typename JoinStrategy
+>
+struct linestring_buffer
+{
+ typedef typename coordinate_type<Polygon>::type coordinate_type;
+ typedef typename point_type<Polygon>::type output_point_type;
+ typedef model::referring_segment<output_point_type const> segment_type;
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ typedef typename ring_type<Polygon>::type ring_type;
+#endif
+
+ template
+ <
+ typename Inserter,
+ typename Iterator
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+ >
+ static inline void iterate(Inserter& inserter,
+ Iterator begin, Iterator end,
+ buffer_side_selector side,
+ DistanceStrategy const& distance,
+ JoinStrategy const& join
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+#endif
+ )
+ {
+ output_point_type previous_p1, previous_p2;
+ output_point_type first_p1, first_p2;
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ int index = 0;
+#endif
+
+ bool first = true;
+
+ Iterator it = begin;
+ for (Iterator prev = it++; it != end; ++it)
+ {
+ if (! detail::equals::equals_point_point(*prev, *it))
+ {
+ bool skip = false;
+
+ // Simulate a vector d (dx,dy)
+ coordinate_type dx = get<0>(*it) - get<0>(*prev);
+ coordinate_type dy = get<1>(*it) - get<1>(*prev);
+
+ // For normalization [0,1] (=dot product d.d, sqrt)
+ coordinate_type length = sqrt(dx * dx + dy * dy);
+
+ // Because coordinates are not equal, length should not be zero
+ BOOST_ASSERT((! geometry::math::equals(length, 0)));
+
+ // Generate the normalized perpendicular p, to the left (ccw)
+ coordinate_type px = -dy / length;
+ coordinate_type py = dx / length;
+
+ output_point_type p1, p2;
+
+ coordinate_type d = distance.apply(*prev, *it, side);
+
+ set<0>(p2, get<0>(*it) + px * d);
+ set<1>(p2, get<1>(*it) + py * d);
+
+ set<0>(p1, get<0>(*prev) + px * d);
+ set<1>(p1, get<1>(*prev) + py * d);
+
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ ring_type block;
+ block.push_back(*prev);
+ block.push_back(*it);
+ block.push_back(p2);
+ block.push_back(p1);
+ block.push_back(*prev);
+
+ mapper.map(block, "opacity:0.4;fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:1");
+#endif
+ }
+
+ if (! first)
+ {
+ output_point_type p;
+ segment_type s1(p1, p2);
+ segment_type s2(previous_p1, previous_p2);
+ if (line_line_intersection<output_point_type, segment_type>::apply(s1, s2, p))
+ {
+ join.apply(p, *prev, previous_p2, p1,
+ distance.apply(*prev, *it, side),
+ inserter.get_ring());
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ mapper.map(p, "fill:rgb(0,0,0);", 3);
+
+ std::ostringstream out;
+ out << index++;
+ mapper.text(p, out.str(), "fill:rgb(0,0,0);font-family='Arial';", 5, 5);
+#endif
+ }
+ }
+ else
+ {
+ skip = false;
+ }
+ }
+ else
+ {
+ first = false;
+ first_p1 = p1;
+ first_p2 = p2;
+
+ inserter.insert(p1);
+ }
+
+ if (! skip)
+ {
+ previous_p1 = p1;
+ previous_p2 = p2;
+ prev = it;
+ }
+ }
+ }
+
+ // Last one
+ inserter.insert(previous_p2);
+ }
+
+
+ template
+ <
+ typename Inserter
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+ >
+ static inline void apply(Linestring const& linestring, Inserter& inserter,
+ DistanceStrategy const& distance,
+ JoinStrategy const& join
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+#endif
+ )
+ {
+ typedef typename boost::range_iterator
+ <
+ Linestring const
+ >::type iterator_type;
+
+ inserter.start_ring();
+
+ iterate(inserter, boost::begin(linestring), boost::end(linestring),
+ buffer_side_left,
+ distance, join
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , mapper
+#endif
+ );
+
+ iterate(inserter, boost::rbegin(linestring), boost::rend(linestring),
+ buffer_side_right, distance, join
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , mapper
+#endif
+ );
+
+ inserter.close_and_insert_ring();
+ }
+};
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINESTRING_BUFFER_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/polygon_buffer.hpp b/src/boost/geometry/extensions/algorithms/buffer/polygon_buffer.hpp
new file mode 100644
index 0000000..101de1f
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/polygon_buffer.hpp
@@ -0,0 +1,231 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_POLYGON_BUFFER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_POLYGON_BUFFER_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp>
+
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+template <typename RingInput, typename RingOutput, typename JoinStrategy>
+struct ring_buffer
+{
+ typedef typename point_type<RingOutput>::type output_point_type;
+ typedef typename coordinate_type<output_point_type>::type coordinate_type;
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ template <typename Mapper>
+#endif
+ static inline void apply(RingInput const& ring, RingOutput& buffered,
+ coordinate_type distance,
+ JoinStrategy const& join_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+#endif
+ )
+ {
+ typedef model::referring_segment<output_point_type const> segment_type;
+ typedef typename boost::range_iterator
+ <
+ RingInput const
+ >::type iterator_type;
+
+ output_point_type previous_p1, previous_p2;
+ output_point_type first_p1, first_p2;
+ bool first = true;
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ int index = 0;
+#endif
+
+ iterator_type it = boost::begin(ring);
+ for (iterator_type prev = it++;
+ it != boost::end(ring); ++it)
+ {
+ if (! detail::equals::equals_point_point(*prev, *it))
+ {
+ bool skip = false;
+
+ // Generate a block along (int most cases to the left of) the segment
+
+ // Simulate a vector d (dx,dy)
+ coordinate_type dx = get<0>(*it) - get<0>(*prev);
+ coordinate_type dy = get<1>(*it) - get<1>(*prev);
+
+
+ // For normalization [0,1] (=dot product d.d, sqrt)
+ coordinate_type length = sqrt(dx * dx + dy * dy);
+
+ // Because coordinates are not equal, length should not be zero
+ BOOST_ASSERT((! geometry::math::equals(length, 0)));
+
+ // Generate the normalized perpendicular p, to the left (ccw)
+ coordinate_type px = -dy / length;
+ coordinate_type py = dx / length;
+
+ output_point_type p1, p2;
+
+ coordinate_type d = distance;
+
+ set<0>(p2, get<0>(*it) + px * d);
+ set<1>(p2, get<1>(*it) + py * d);
+
+ set<0>(p1, get<0>(*prev) + px * d);
+ set<1>(p1, get<1>(*prev) + py * d);
+
+ {
+ RingOutput block;
+ block.push_back(*prev);
+ block.push_back(*it);
+ block.push_back(p2);
+ block.push_back(p1);
+ block.push_back(*prev);
+
+ #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ mapper.map(block, "opacity:0.4;fill:rgb(255,128,0);stroke:rgb(0,0,0);stroke-width:1");
+ #endif
+ }
+
+ if (! first)
+ {
+ output_point_type p;
+ segment_type s1(p1, p2);
+ segment_type s2(previous_p1, previous_p2);
+ if (line_line_intersection<output_point_type, segment_type>::apply(s1, s2, p))
+ {
+ join_strategy.apply(p, *prev, previous_p2, p1, distance, buffered);
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ mapper.map(p, "fill:rgb(0,0,0);", 3);
+
+ std::ostringstream out;
+ out << index++;
+ mapper.text(p, out.str(), "fill:rgb(0,0,0);font-family='Arial';", 5, 5);
+#endif
+ }
+ }
+ else
+ {
+ skip = false;
+ }
+ }
+ else
+ {
+ first = false;
+ first_p1 = p1;
+ first_p2 = p2;
+ }
+
+ if (! skip)
+ {
+ previous_p1 = p1;
+ previous_p2 = p2;
+ prev = it;
+ }
+ }
+ }
+
+ // Last one
+ {
+ output_point_type p;
+ segment_type s1(previous_p1, previous_p2);
+ segment_type s2(first_p1, first_p2);
+ line_line_intersection<output_point_type, segment_type>::apply(s1, s2, p);
+
+ join_strategy.apply(p, *boost::begin(ring), previous_p2, first_p1, distance, buffered);
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ mapper.map(p, "fill:rgb(0,0,0);", 3);
+ std::ostringstream out;
+ out << index++;
+ mapper.text(p, out.str(), "fill:rgb(0,0,0);font-family='Arial';", 5, 5);
+#endif
+ }
+
+ // Close the generated buffer
+ {
+ output_point_type p = *boost::begin(buffered);
+ buffered.push_back(p);
+ }
+ }
+};
+
+
+
+template <typename PolygonInput, typename PolygonOutput, typename JoinStrategy>
+struct polygon_buffer
+{
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ template <typename Mapper>
+#endif
+ static inline void apply(PolygonInput const& polygon, PolygonOutput& buffered,
+ typename coordinate_type<PolygonOutput>::type distance,
+ JoinStrategy const& join_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+#endif
+ )
+ {
+ geometry::clear(buffered);
+
+ typedef typename ring_type<PolygonInput>::type input_ring_type;
+ typedef typename ring_type<PolygonOutput>::type output_ring_type;
+
+ typedef ring_buffer<input_ring_type, output_ring_type, JoinStrategy> policy;
+ policy::apply(exterior_ring(polygon), exterior_ring(buffered),
+ distance, join_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , mapper
+#endif
+ );
+
+ typename interior_return_type<PolygonInput const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ output_ring_type ring;
+ policy::apply(*it, ring, distance, join_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , mapper
+#endif
+ );
+ interior_rings(buffered).push_back(ring);
+ }
+ }
+};
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_POLYGON_BUFFER_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/remove_within_distance.hpp b/src/boost/geometry/extensions/algorithms/buffer/remove_within_distance.hpp
new file mode 100644
index 0000000..e0f88e1
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/remove_within_distance.hpp
@@ -0,0 +1,151 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHM_REMOVE_WITHIN_DISTANCE_HPP
+#define BOOST_GEOMETRY_ALGORITHM_REMOVE_WITHIN_DISTANCE_HPP
+
+
+#include <algorithm>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+
+#include <boost/geometry/core/interior_rings.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+template<typename Geometry, typename GeometryInput, typename T>
+struct remove_false_ring_predicate
+{
+private :
+ typedef typename point_type<Geometry>::type point_type;
+
+ GeometryInput const& m_input;
+ T m_distance;
+
+public :
+ remove_false_ring_predicate(GeometryInput const& input,
+ T const& distance)
+ : m_input(input)
+ , m_distance(distance)
+ {
+ }
+
+ inline bool operator()(Geometry const& geometry)
+ {
+ point_type point, point_input;
+ if (geometry::point_on_border(point, geometry, false)
+ && geometry::point_on_border(point_input, m_input, false))
+ {
+ if (m_distance > T())
+ {
+ // If the input is within the output, it is acceptable
+ if (geometry::within(point_input, geometry))
+ {
+ return false;
+ }
+
+ // Check the distance to the input geometry
+ // (for a polygon, this is: the distance from OUTSIDE
+ // to the border
+ T d = geometry::distance(point, m_input);
+ if (d < m_distance)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+};
+
+
+
+template<typename Polygon, typename Geometry>
+struct polygon_remove_false_rings
+{
+ template <typename T>
+ static inline void apply(Polygon& polygon, Geometry const& input, T const& distance)
+ {
+ interior_rings(polygon).erase
+ (
+ std::remove_if
+ (
+ boost::begin(interior_rings(polygon)),
+ boost::end(interior_rings(polygon)),
+ remove_false_ring_predicate
+ <
+ typename ring_type<Polygon>::type,
+ Geometry,
+ T
+ >(input, distance)
+ ),
+ boost::end(interior_rings(polygon))
+ );
+
+ }
+};
+
+
+template<typename Collection, typename Geometry, typename T>
+inline void collection_remove_within_distance(Collection& dissolved,
+ Geometry const& input,
+ T const& distance)
+{
+ typedef typename boost::range_value<Collection>::type polygon_type;
+ // 1: remove all polygons which are false positive (positive,
+ // but too close to the input geometry
+ dissolved.erase
+ (
+ std::remove_if(boost::begin(dissolved), boost::end(dissolved),
+ remove_false_ring_predicate
+ <
+ polygon_type,
+ Geometry,
+ T
+ >(input, distance)),
+ boost::end(dissolved)
+ );
+
+ // 2: within all polygons, remove false negative interior rings
+ for (typename boost::range_iterator<Collection>::type
+ it = boost::begin(dissolved);
+ it != boost::end(dissolved);
+ ++it)
+ {
+ polygon_remove_false_rings
+ <
+ typename boost::range_value<Collection>::type,
+ Geometry
+ >::apply(*it, input, distance);
+ }
+}
+
+
+}} // namespace detail::buffer
+
+
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHM_REMOVE_WITHIN_DISTANCE_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/sectionalizing_buffer.hpp b/src/boost/geometry/extensions/algorithms/buffer/sectionalizing_buffer.hpp
new file mode 100644
index 0000000..7e7d3a5
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/sectionalizing_buffer.hpp
@@ -0,0 +1,167 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SECTIONALIZING_BUFFER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SECTIONALIZING_BUFFER_HPP
+
+#include <cstddef>
+
+#include <boost/foreach.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+#include <boost/geometry/extensions/algorithms/detail/buffer/intersecting_inserter.hpp>
+#include <boost/geometry/extensions/algorithms/detail/buffer/linestring_buffer.hpp>
+#include <boost/geometry/extensions/algorithms/detail/buffer/line_line_intersection.hpp>
+
+#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
+#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
+
+#include <boost/geometry/extensions/algorithms/dissolve.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+
+template
+<
+ typename GeometryOut, typename Geometry,
+ typename DistanceStrategy,
+ typename JoinStrategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+>
+void sectionalizing_buffer(Geometry const& geometry,
+ std::vector<GeometryOut>& buffered,
+ DistanceStrategy const& distance_strategy,
+ JoinStrategy const& join_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+#endif
+ )
+{
+ typedef typename point_type<Geometry>::type point_type;
+ typedef geometry::box<point_type> box_type;
+ typedef geometry::sections<box_type, 2> sections_type;
+ typedef typename geometry::ring_type<GeometryOut>::type ring_type;
+
+ // TEMPORARY
+ typedef intersecting_inserter
+ <
+ std::vector<GeometryOut>
+ > inserter_type;
+
+
+ sections_type sections;
+ geometry::sectionalize(geometry, sections);
+
+
+
+ // Buffer all sections separately, and put them in a temporary vector
+ std::vector<GeometryOut> buffered_sections;
+ BOOST_FOREACH(typename sections_type::value_type const& section, sections)
+ {
+ if (! section.duplicate)
+ {
+ typedef typename boost::range_iterator
+ <
+ typename geometry::detail::range_type<Geometry>::type const
+ >::type iterator_type;
+
+
+ inserter_type inserter(buffered_sections);
+
+ iterator_type begin, end;
+ typedef std::pair<iterator_type, iterator_type> section_range;
+
+TODO: UPDATE: get _ section IS OBSOLETE NOW AND DISCARDED.
+TAKE range_by_section AND ADD section.begin_index/section.end_index
+
+ geometry::get _ section(geometry, section, begin, end); // get_section is DISCARDED
+ geometry::detail::buffer::linestring_buffer
+ <
+ section_range, ring_type, DistanceStrategy, JoinStrategy
+ >::apply(std::make_pair(begin, end), inserter,
+ distance_strategy,
+ join_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , mapper
+#endif
+ );
+ }
+ }
+
+ // IF there are bowl-like shapes, there can still be self-intersections
+ std::vector<GeometryOut> dissolved;
+ BOOST_FOREACH(GeometryOut const& p, buffered_sections)
+ {
+ geometry::dissolve(p, dissolved);
+ }
+
+ /*BOOST_FOREACH(GeometryOut const& p, buffered_sections)
+ {
+ if (geometry::intersects(p))
+ {
+ //std::cout << ".";
+ }
+ }*/
+
+ // TEMP
+ //buffered.swap(dissolved);
+ //return;
+ // END TEMP
+
+
+ BOOST_FOREACH(GeometryOut const& p, dissolved)
+ {
+ if (buffered.empty())
+ {
+ buffered.push_back(p);
+ //geometry::union_inserter<GeometryOut>(geometry, p, std::back_inserter(buffered));
+ }
+ else if (boost::size(buffered) == 1)
+ {
+ std::vector<GeometryOut> unioned;
+ geometry::union_inserter<GeometryOut>(buffered.front(), p, std::back_inserter(unioned));
+ buffered.swap(unioned);
+ }
+ else
+ {
+ std::cerr << " D " << buffered.size();
+ /*std::vector<GeometryOut> dissolved;
+ dissolved.push_back(p);
+ geometry::dissolver(buffered, dissolved);
+ dissolved.swap(buffered);*/
+ }
+ }
+
+ // Output
+}
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SECTIONALIZING_BUFFER_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/segmenting_buffer.hpp b/src/boost/geometry/extensions/algorithms/buffer/segmenting_buffer.hpp
new file mode 100644
index 0000000..7b99a74
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/segmenting_buffer.hpp
@@ -0,0 +1,350 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SEGMENTING_BUFFER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SEGMENTING_BUFFER_HPP
+
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/foreach.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+#include <boost/geometry/extensions/strategies/buffer_join_round.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+
+
+#include <boost/geometry/extensions/algorithms/dissolve.hpp>
+
+
+// TEMPORARY do not use yet.
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+template <typename Point, typename PointOut, typename DistanceType>
+inline bool calculate_parallels(Point const& point1, Point const& point2,
+ PointOut& p1, PointOut& p2, DistanceType const& distance)
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+
+ // Simulate a vector d (dx,dy)
+ coordinate_type dx = get<0>(point2) - get<0>(point1);
+ coordinate_type dy = get<1>(point2) - get<1>(point1);
+
+ // For normalization [0,1] (=dot product d.d, sqrt)
+ // TODO: promote to non-integer
+ coordinate_type length = sqrt(dx * dx + dy * dy);
+
+ // Because coordinates are not equal, should been checked before, length should not be zero
+ if(geometry::math::equals(length, 0))
+ {
+ return false;
+ }
+
+ // Generate the normalized perpendicular p, to the left (ccw)
+ coordinate_type px = -dy / length;
+ coordinate_type py = dx / length;
+
+ set<0>(p1, get<0>(point1) + px * distance);
+ set<1>(p1, get<1>(point1) + py * distance);
+
+ set<0>(p2, get<0>(point2) + px * distance);
+ set<1>(p2, get<1>(point2) + py * distance);
+ return true;
+}
+
+
+
+template
+<
+ typename GeometryOut, typename Range,
+ typename DistanceStrategy,
+ typename JoinStrategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+>
+struct per_segment_buffer
+{
+ typedef typename point_type<Range>::type input_point_type;
+ typedef typename point_type<GeometryOut>::type point_type;
+ typedef typename coordinate_type<point_type>::type coordinate_type;
+ typedef coordinate_type distance_type; // TODO promote to FP
+ typedef model::segment<point_type const> segment_type;
+ typedef typename geometry::ring_type<GeometryOut>::type ring_type;
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<point_type>::type>::type side;
+
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+
+ static inline void calculate_tail(input_point_type const& tail, input_point_type const& head,
+ point_type& tail_left, point_type& tail_right,
+ distance_type& distance_left,
+ distance_type& distance_right,
+ distance_type& buffered_length)
+ {
+ coordinate_type ext_x = get<0>(head) - get<0>(tail);
+ coordinate_type ext_y = get<1>(head) - get<1>(tail);
+ distance_type segment_length = sqrt(ext_x * ext_x + ext_y * ext_y);
+
+ if (buffered_length < geometry::math::abs(distance_left))
+ {
+ distance_left = buffered_length * distance_left < 0 ? -1.0 : 1.0;
+ }
+ if (buffered_length < geometry::math::abs(distance_right))
+ {
+ distance_right = buffered_length * distance_right < 0 ? -1.0 : 1.0;
+ }
+
+ distance_type prop_left = geometry::math::abs(distance_left) / segment_length;
+ distance_type prop_right = geometry::math::abs(distance_right) / segment_length;
+
+ set<0>(tail_left, get<0>(tail) - ext_x * prop_left);
+ set<1>(tail_left, get<1>(tail) - ext_y * prop_left);
+ set<0>(tail_right, get<0>(tail) - ext_x * prop_right);
+ set<1>(tail_right, get<1>(tail) - ext_y * prop_right);
+
+ buffered_length += segment_length;
+ }
+
+
+ static inline void calculate_head(input_point_type const& tail, input_point_type const& head,
+ point_type& head_left, point_type& head_right,
+ distance_type& distance_left,
+ distance_type& distance_right,
+ distance_type const& rest_length)
+ {
+ coordinate_type ext_x = get<0>(head) - get<0>(tail);
+ coordinate_type ext_y = get<1>(head) - get<1>(tail);
+ distance_type segment_length = sqrt(ext_x * ext_x + ext_y * ext_y);
+
+ if (rest_length < distance_left)
+ {
+ distance_left = rest_length;
+ }
+ if (rest_length < distance_right)
+ {
+ distance_right = rest_length;
+ }
+
+ distance_type prop_left = distance_left / segment_length;
+ distance_type prop_right = distance_right / segment_length;
+
+ set<0>(head_left, get<0>(head) + ext_x * prop_left);
+ set<1>(head_left, get<1>(head) + ext_y * prop_left);
+ set<0>(head_right, get<0>(head) + ext_x * prop_right);
+ set<1>(head_right, get<1>(head) + ext_y * prop_right);
+ }
+
+ static inline void apply(Range const& range,
+ std::vector<GeometryOut>& buffered,
+ DistanceStrategy const& distance_strategy,
+ JoinStrategy const& join_strategy
+ #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+ #endif
+ )
+ {
+ // Buffer all segments separately, and put them in a temporary vector
+ std::vector<GeometryOut> buffered_pieces;
+
+ bool first = true;
+
+ strategy::buffer::join_round2<point_type> new_join;
+ //strategy::buffer::join_none<point_type> new_join;
+
+ distance_type range_length = geometry::length(range);
+ distance_type buffered_length = coordinate_type();
+
+ iterator_type it = boost::begin(range);
+ //iterator_type it_c = boost::end(range);
+ for (iterator_type previous = it++;
+ it != boost::end(range);
+ ++it)
+ {
+ bool const last = it + 1 == boost::end(range);
+
+ distance_type distance_left = distance_strategy.apply(
+ *previous, *it, buffer_side_left);
+ distance_type distance_right = distance_strategy.apply(
+ *previous, *it, buffer_side_right);
+
+ point_type left_ab_p1, left_ab_p2, right_ab_p1, right_ab_p2;
+
+ if (detail::disjoint::disjoint_point_point(*previous, *it)
+ && calculate_parallels(*previous, *it, left_ab_p1, left_ab_p2,
+ distance_left)
+ && calculate_parallels(*previous, *it, right_ab_p1, right_ab_p2,
+ -distance_right)
+ )
+ {
+ {
+ point_type tail_left, tail_right, head_left, head_right;
+
+ // For flat buffers, generate corners only if outside range of buffer_distance
+ distance_type distance_tail_left = distance_left;
+ distance_type distance_tail_right = distance_right;
+ distance_type distance_head_left = distance_left;
+ distance_type distance_head_right = distance_right;
+
+ calculate_tail(*previous, *it,
+ tail_left, tail_right,
+ distance_tail_left, distance_tail_right,
+ buffered_length);
+
+ distance_type const rest_length = range_length - buffered_length;
+
+ calculate_head(*previous, *it,
+ head_left, head_right,
+ distance_head_left, distance_head_right,
+ rest_length);
+
+ // Add non-axis aligned rectangle
+ buffered_pieces.resize(buffered_pieces.size() + 1);
+ ring_type& ring = exterior_ring(buffered_pieces.back());
+ ring.push_back(left_ab_p1);
+ ring.push_back(left_ab_p2);
+
+ if (! last)
+ {
+ new_join.apply(*it, left_ab_p2, left_ab_p2, head_left,
+ distance_left, distance_head_left,
+ std::back_inserter(ring));
+
+ ring.push_back(head_left);
+ ring.push_back(head_right);
+
+ new_join.apply(*it, right_ab_p2, head_right, right_ab_p2,
+ distance_right, distance_head_right,
+ std::back_inserter(ring));
+ }
+
+ ring.push_back(right_ab_p2);
+ ring.push_back(right_ab_p1);
+
+ if (! first)
+ {
+ new_join.apply(*previous, right_ab_p1, right_ab_p1, tail_right,
+ distance_right, distance_tail_right,
+ std::back_inserter(ring));
+
+ ring.push_back(tail_right);
+ ring.push_back(tail_left);
+
+ new_join.apply(*previous, left_ab_p1, tail_left, left_ab_p1,
+ distance_left, distance_tail_left,
+ std::back_inserter(ring));
+ }
+
+ ring.push_back(left_ab_p1);
+ }
+
+ previous = it;
+
+ first = false;
+ }
+ }
+
+ // TEMP, uncomment to see what was actually generated
+ //buffered.swap(buffered_pieces);
+ //return;
+ // END TEMP
+
+
+
+ BOOST_FOREACH(GeometryOut const& p, buffered_pieces)
+ {
+ if (buffered.empty())
+ {
+ buffered.push_back(p);
+ }
+ else if (boost::size(buffered) == 1)
+ {
+ std::vector<GeometryOut> unioned;
+ geometry::union_inserter<GeometryOut>(buffered.front(), p, std::back_inserter(unioned));
+ buffered.swap(unioned);
+ }
+ else
+ {
+ std::cerr << " D " << buffered.size();
+ /*std::vector<GeometryOut> dissolved;
+ dissolved.push_back(p);
+ geometry::dissolver(buffered, dissolved);
+ dissolved.swap(buffered);*/
+ }
+ }
+
+ /***
+ std::vector<GeometryOut> dissolved;
+ BOOST_FOREACH(GeometryOut const& p, buffered)
+ {
+ geometry::dissolve(p, dissolved);
+ }
+ dissolved.swap(buffered);
+ ***/
+
+ // Output
+ }
+};
+
+
+
+template
+<
+ typename GeometryOut, typename Geometry,
+ typename DistanceStrategy,
+ typename JoinStrategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+>
+inline void segmenting_buffer(Geometry const& geometry,
+ std::vector<GeometryOut>& buffered,
+ DistanceStrategy const& distance_strategy,
+ JoinStrategy const& join_strategy
+ #ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+ #endif
+ )
+{
+ per_segment_buffer
+ <
+ GeometryOut, Geometry,
+ DistanceStrategy, JoinStrategy
+ >::apply(geometry, buffered, distance_strategy, join_strategy);
+}
+
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SEGMENTING_BUFFER_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/splitting_buffer.hpp b/src/boost/geometry/extensions/algorithms/buffer/splitting_buffer.hpp
new file mode 100644
index 0000000..9514b22
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/splitting_buffer.hpp
@@ -0,0 +1,116 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SPLITTING_BUFFER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SPLITTING_BUFFER_HPP
+
+#include <cstddef>
+
+#include <boost/foreach.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+#include <boost/geometry/extensions/algorithms/detail/buffer/intersecting_inserter.hpp>
+#include <boost/geometry/extensions/algorithms/detail/buffer/linestring_buffer.hpp>
+#include <boost/geometry/extensions/algorithms/detail/buffer/line_line_intersection.hpp>
+
+
+#include <boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp>
+#include <boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+template
+<
+ typename GeometryOut, typename Geometry,
+ typename DistanceStrategy,
+ typename JoinStrategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+>
+inline void splitting_buffer(Geometry const& geometry,
+ std::vector<GeometryOut>& buffered,
+ DistanceStrategy const& distance_strategy,
+ JoinStrategy const& join_strategy
+
+ , int option
+ )
+{
+ typedef typename ring_type<GeometryOut>::type ring_type;
+ typedef detail::buffer::intersecting_inserter
+ <
+ std::vector<GeometryOut>
+ > inserter_type;
+
+
+ inserter_type inserter(buffered);
+
+ detail::buffer::linestring_buffer
+ <
+ Geometry, GeometryOut, DistanceStrategy, JoinStrategy
+ >::apply(geometry, inserter, distance_strategy, join_strategy);
+
+ if (option == 0)
+ {
+ return;
+ }
+
+ std::vector<ring_type> rings;
+ BOOST_FOREACH(GeometryOut const& polygon, buffered)
+ {
+//std::cout << geometry::wkt(polygon) << " ; POLYGON" << std::endl;
+ geometry::split_rings(polygon, rings);
+ }
+
+ if (option == 1)
+ {
+ buffered.resize(rings.size());
+ int i = 0;
+ BOOST_FOREACH(ring_type const& ring, rings)
+ {
+ exterior_ring(buffered[i++]) = ring;
+ }
+ return;
+ }
+
+ std::vector<GeometryOut> buffered_and_unioned;
+ geometry::dissolver(rings, buffered_and_unioned);
+
+ std::vector<GeometryOut> buffered_and_assembled;
+ detail::overlay::assemble<GeometryOut>(buffered_and_unioned,
+ std::map<ring_identifier, int>(),
+ buffered_and_unioned[0], buffered_and_unioned[0], 1, true, true,
+ std::back_inserter(buffered_and_assembled));
+
+ buffered = buffered_and_assembled;
+}
+
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_SPLITTING_BUFFER_HPP
diff --git a/src/boost/geometry/extensions/algorithms/buffer/traversing_buffer.hpp b/src/boost/geometry/extensions/algorithms/buffer/traversing_buffer.hpp
new file mode 100644
index 0000000..b64129c
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/buffer/traversing_buffer.hpp
@@ -0,0 +1,89 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TRAVERSING_BUFFER_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TRAVERSING_BUFFER_HPP
+
+#include <cstddef>
+
+#include <boost/foreach.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/intersecting_inserter.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/linestring_buffer.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp>
+
+
+#include <boost/geometry/extensions/algorithms/dissolve.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer
+{
+
+
+template
+<
+ typename GeometryOut, typename Geometry,
+ typename DistanceStrategy,
+ typename JoinStrategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , typename Mapper
+#endif
+>
+inline void traversing_buffer(Geometry const& geometry,
+ std::vector<GeometryOut>& buffered,
+ DistanceStrategy const& distance_strategy,
+ JoinStrategy const& join_strategy
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ , Mapper& mapper
+#endif
+ )
+{
+ typedef typename ring_type<GeometryOut>::type ring_type;
+ typedef detail::buffer::intersecting_inserter
+ <
+ std::vector<GeometryOut>
+ > inserter_type;
+
+
+ inserter_type inserter(buffered);
+
+ detail::buffer::linestring_buffer
+ <
+ Geometry, GeometryOut, DistanceStrategy, JoinStrategy
+ >::apply(geometry, inserter, distance_strategy, join_strategy);
+
+ std::vector<GeometryOut> buffered_and_assembled;
+ detail::overlay::assemble<GeometryOut>(buffered,
+ std::map<ring_identifier, int>(),
+ buffered[0], buffered[0], 1, true, true,
+ std::back_inserter(buffered_and_assembled));
+
+ buffered = buffered_and_assembled;
+}
+
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_TRAVERSING_BUFFER_HPP
diff --git a/src/boost/geometry/extensions/algorithms/connect.hpp b/src/boost/geometry/extensions/algorithms/connect.hpp
new file mode 100644
index 0000000..0464a1a
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/connect.hpp
@@ -0,0 +1,581 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_CONNECT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_CONNECT_HPP
+
+#include <map>
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/strategies/default_distance_result.hpp>
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/io/dsv/write.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace connect
+{
+
+
+template <typename Point>
+struct node
+{
+ int index;
+ bool is_from;
+ Point point;
+
+ node(int i, bool f, Point const& p)
+ : index(i)
+ , is_from(f)
+ , point(p)
+ {}
+
+ node()
+ : index(-1)
+ , is_from(false)
+ {}
+};
+
+template <typename Point>
+struct map_policy
+{
+ typedef typename strategy::distance::services::default_strategy
+ <
+ point_tag, Point
+ >::type strategy_type;
+
+ // Have a map<point, <index,start/end> > such that we can find
+ // the corresponding point on each end. Note that it uses the
+ // default "equals" for the point-type
+ typedef std::map
+ <
+ Point,
+ std::vector<node<Point> >,
+ geometry::less<Point>
+ > map_type;
+
+ typedef typename map_type::const_iterator map_iterator_type;
+ typedef typename std::vector<node<Point> >::const_iterator vector_iterator_type;
+
+ typedef Point point_type;
+ typedef typename default_distance_result<Point>::type distance_result_type;
+
+
+ map_type map;
+
+
+ inline bool find_start(node<Point>& object,
+ std::map<int, bool>& included,
+ int expected_count = 1)
+ {
+ for (map_iterator_type it = map.begin();
+ it != map.end();
+ ++it)
+ {
+ if ((expected_count == 1 && boost::size(it->second) == 1)
+ || (expected_count > 1 && boost::size(it->second) > 1))
+ {
+ for (vector_iterator_type vit = it->second.begin();
+ vit != it->second.end();
+ ++vit)
+ {
+ if (! included[vit->index])
+ {
+ included[vit->index] = true;
+ object = *vit;
+ return true;
+ }
+ }
+ }
+ }
+
+ // Not found with one point, try one with two points
+ // to find rings
+ if (expected_count == 1)
+ {
+ return find_start(object, included, 2);
+ }
+
+ return false;
+ }
+
+ inline void add(int index, Point const& p, bool is_from)
+ {
+ map[p].push_back(node<Point>(index, is_from, p));
+ }
+
+
+ template <typename LineString>
+ inline void add(int index, LineString const& ls)
+ {
+ if (boost::size(ls) > 0)
+ {
+ add(index, *boost::begin(ls), true);
+ add(index, *(boost::end(ls) - 1), false);
+ }
+ }
+
+ inline node<Point> find_closest(Point const& p1, std::map<int, bool>& included)
+ {
+ std::vector<node<Point> > const& range = map[p1];
+
+ node<Point> closest;
+
+
+ // Alternatively, we might look for the closest points
+ if (boost::size(range) == 0)
+ {
+ std::cout << "nothing found" << std::endl;
+ return closest;
+ }
+
+ // 2c: for all candidates get closest one
+ strategy_type strategy;
+
+ distance_result_type min_dist = strategy::distance::services
+ ::result_from_distance<strategy_type>::apply(strategy, 100);
+
+ for (vector_iterator_type it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ if (! included[it->index])
+ {
+ distance_result_type d = geometry::comparable_distance(p1, it->point);
+ if (d < min_dist)
+ {
+ closest = *it;
+ min_dist = d;
+
+ //std::cout << "TO " << geometry::wkt(p2) << std::endl;
+ }
+ }
+ }
+ return closest;
+ }
+
+};
+
+
+template <typename Point>
+struct fuzzy_policy
+{
+ typedef typename strategy::distance::services::default_strategy
+ <
+ point_tag, Point
+ >::type strategy_type;
+
+ // Have a map<point, <index,start/end> > such that we can find
+ // the corresponding point on each end. Note that it uses the
+ // default "equals" for the point-type
+ typedef std::vector
+ <
+ std::pair
+ <
+ Point,
+ std::vector<node<Point> >
+ >
+ > map_type;
+
+ typedef typename map_type::const_iterator map_iterator_type;
+ typedef typename std::vector<node<Point> >::const_iterator vector_iterator_type;
+
+ typedef Point point_type;
+ typedef typename default_distance_result<Point>::type distance_result_type;
+
+
+ map_type map;
+ typename coordinate_type<Point>::type m_limit;
+
+
+ fuzzy_policy(typename coordinate_type<Point>::type limit)
+ : m_limit(limit)
+ {}
+
+ inline bool find_start(node<Point>& object,
+ std::map<int, bool>& included,
+ int expected_count = 1)
+ {
+ for (map_iterator_type it = map.begin();
+ it != map.end();
+ ++it)
+ {
+ if ((expected_count == 1 && boost::size(it->second) == 1)
+ || (expected_count > 1 && boost::size(it->second) > 1))
+ {
+ for (vector_iterator_type vit = it->second.begin();
+ vit != it->second.end();
+ ++vit)
+ {
+ if (! included[vit->index])
+ {
+ included[vit->index] = true;
+ object = *vit;
+ return true;
+ }
+ }
+ }
+ }
+
+ // Not found with one point, try one with two points
+ // to find rings
+ if (expected_count == 1)
+ {
+ return find_start(object, included, 2);
+ }
+
+ return false;
+ }
+
+ inline typename boost::range_iterator<map_type>::type fuzzy_closest(Point const& p)
+ {
+ typename boost::range_iterator<map_type>::type closest = boost::end(map);
+
+ for (typename boost::range_iterator<map_type>::type it = boost::begin(map);
+ it != boost::end(map);
+ ++it)
+ {
+ distance_result_type d = geometry::distance(p, it->first);
+ if (d < m_limit)
+ {
+ if (closest == boost::end(map))
+ {
+ closest = it;
+ }
+ else
+ {
+ distance_result_type dc = geometry::distance(p, closest->first);
+ if (d < dc)
+ {
+ closest = it;
+ }
+ }
+ }
+ }
+ return closest;
+ }
+
+
+ inline void add(int index, Point const& p, bool is_from)
+ {
+ // Iterate through all points and get the closest one.
+ typename boost::range_iterator<map_type>::type it = fuzzy_closest(p);
+ if (it == map.end())
+ {
+ map.resize(map.size() + 1);
+ map.back().first = p;
+ it = map.end() - 1;
+ }
+ it->second.push_back(node<Point>(index, is_from, p));
+ }
+
+
+ template <typename LineString>
+ inline void add(int index, LineString const& ls)
+ {
+ if (boost::size(ls) > 0)
+ {
+ add(index, *boost::begin(ls), true);
+ add(index, *(boost::end(ls) - 1), false);
+ }
+ }
+
+ inline node<Point> find_closest(Point const& p1, std::map<int, bool>& included)
+ {
+ namespace services = strategy::distance::services;
+
+ node<Point> closest;
+
+ typename boost::range_iterator<map_type>::type it = fuzzy_closest(p1);
+ if (it == map.end())
+ {
+ return closest;
+ }
+
+ std::vector<node<Point> > const& range = it->second;
+
+
+
+ // Alternatively, we might look for the closest points
+ if (boost::size(range) == 0)
+ {
+ std::cout << "nothing found" << std::endl;
+ return closest;
+ }
+
+ // 2c: for all candidates get closest one
+ strategy_type strategy;
+ distance_result_type min_dist = strategy::distance::services
+ ::result_from_distance<strategy_type>::apply(strategy, 100);
+
+ for (vector_iterator_type it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ if (! included[it->index])
+ {
+ distance_result_type d = geometry::comparable_distance(p1, it->point);
+ if (d < min_dist)
+ {
+ closest = *it;
+ min_dist = d;
+
+ //std::cout << "TO " << geometry::wkt(p2) << std::endl;
+ }
+ }
+ }
+ return closest;
+ }
+};
+
+template <typename Policy>
+inline void debug(Policy const& policy)
+{
+ std::cout << "MAP" << std::endl;
+ typedef typename Policy::map_type::const_iterator iterator;
+ typedef typename Policy::point_type point_type;
+
+ for (iterator it=policy.map.begin(); it != policy.map.end(); ++it)
+ {
+ std::cout << geometry::dsv(it->first) << " => " ;
+ std::vector<node<point_type> > const& range =it->second;
+ for (typename std::vector<node<point_type> >::const_iterator
+ vit = boost::begin(range); vit != boost::end(range); ++vit)
+ {
+ std::cout
+ << " (" << vit->index
+ << ", " << (vit->is_from ? "F" : "T")
+ << ")"
+ ;
+ }
+ std::cout << std::endl;
+ }
+}
+
+
+
+
+// Dissolve on multi_linestring tries to create larger linestrings from input,
+// or closed rings.
+
+template <typename Multi, typename GeometryOut, typename Policy>
+struct connect_multi_linestring
+{
+ typedef typename point_type<Multi>::type point_type;
+ typedef typename boost::range_iterator<Multi const>::type iterator_type;
+ typedef typename boost::range_value<Multi>::type linestring_type;
+
+
+ static inline void copy(linestring_type const& ls,
+ GeometryOut& target,
+ bool copy_forward)
+ {
+ if (copy_forward)
+ {
+ std::copy(boost::begin(ls), boost::end(ls),
+ std::back_inserter(target));
+ }
+ else
+ {
+ std::reverse_copy(boost::begin(ls), boost::end(ls),
+ std::back_inserter(target));
+ }
+ }
+
+
+ template <typename OutputIterator>
+ static inline OutputIterator apply(Multi const& multi, Policy& policy, OutputIterator out)
+ {
+ if (boost::size(multi) <= 0)
+ {
+ return out;
+ }
+
+ // 1: fill the map.
+ int index = 0;
+ for (iterator_type it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it, ++index)
+ {
+ policy.add(index, *it);
+ }
+
+ debug(policy);
+
+ std::map<int, bool> included;
+
+ // 2: connect the lines
+
+ // 2a: start with one having a unique starting point
+ node<point_type> starting_point;
+ if (! policy.find_start(starting_point, included))
+ {
+ return out;
+ }
+
+ GeometryOut current;
+ copy(multi[starting_point.index], current, starting_point.is_from);
+
+ bool found = true;
+ while(found)
+ {
+ // 2b: get all candidates, by asking multi-map for range
+ point_type const& p1 = *(boost::end(current) - 1);
+
+ node<point_type> closest = policy.find_closest(p1, included);
+
+ found = false;
+
+ // 2d: if there is a closest one add it
+ if (closest.index >= 0)
+ {
+ found = true;
+ included[closest.index] = true;
+ copy(multi[closest.index], current, closest.is_from);
+ }
+ else if ((included.size() != std::size_t(boost::size(multi))))
+ {
+ // Get one which is NOT found and go again
+ node<point_type> next;
+ if (policy.find_start(next, included))
+ {
+ found = true;
+
+ *out++ = current;
+ geometry::clear(current);
+
+ copy(multi[next.index], current, next.is_from);
+ }
+ }
+ }
+ if (boost::size(current) > 0)
+ {
+ *out++ = current;
+ }
+
+ return out;
+ }
+};
+
+}} // namespace detail::connect
+#endif
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryTag,
+ typename GeometryOutTag,
+ typename Geometry,
+ typename GeometryOut,
+ typename Policy
+>
+struct connect
+{};
+
+
+template<typename Multi, typename GeometryOut, typename Policy>
+struct connect<multi_linestring_tag, linestring_tag, Multi, GeometryOut, Policy>
+ : detail::connect::connect_multi_linestring
+ <
+ Multi,
+ GeometryOut,
+ Policy
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template
+<
+ typename Geometry,
+ typename Collection
+>
+inline void connect(Geometry const& geometry, Collection& output_collection)
+{
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ concept::check<Geometry const>();
+ concept::check<geometry_out>();
+
+ typedef detail::connect::map_policy
+ <
+ typename point_type<Geometry>::type
+ > policy_type;
+
+ policy_type policy;
+
+ dispatch::connect
+ <
+ typename tag<Geometry>::type,
+ typename tag<geometry_out>::type,
+ Geometry,
+ geometry_out,
+ policy_type
+ >::apply(geometry, policy, std::back_inserter(output_collection));
+}
+
+
+
+template
+<
+ typename Geometry,
+ typename Collection
+>
+inline void connect(Geometry const& geometry, Collection& output_collection,
+ typename coordinate_type<Geometry>::type const& limit)
+{
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ concept::check<Geometry const>();
+ concept::check<geometry_out>();
+
+ typedef detail::connect::fuzzy_policy
+ <
+ typename point_type<Geometry>::type
+ > policy_type;
+
+ policy_type policy(limit);
+
+ dispatch::connect
+ <
+ typename tag<Geometry>::type,
+ typename tag<geometry_out>::type,
+ Geometry,
+ geometry_out,
+ policy_type
+ >::apply(geometry, policy, std::back_inserter(output_collection));
+}
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_CONNECT_HPP
diff --git a/src/boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp b/src/boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp
new file mode 100644
index 0000000..0744429
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp
@@ -0,0 +1,640 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DETAIL_OVERLAY_DISSOLVER_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DETAIL_OVERLAY_DISSOLVER_HPP
+
+
+#include <deque>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/algorithms/intersection.hpp>
+#include <boost/geometry/algorithms/union.hpp>
+#include <boost/geometry/algorithms/reverse.hpp>
+
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+
+namespace detail { namespace inserter
+{
+
+
+template<typename Tag1, typename Tag2>
+struct insert_geometry
+{};
+
+template<>
+struct insert_geometry<ring_tag, polygon_tag>
+{
+ template<typename Ring, typename Collection>
+ static inline void apply(Ring const& ring, Collection& collection)
+ {
+ collection.resize(collection.size() + 1);
+ geometry::exterior_ring(collection.back()) = ring;
+ }
+};
+
+
+
+
+template<>
+struct insert_geometry<polygon_tag, polygon_tag>
+{
+ template<typename Geometry, typename Collection>
+ static inline void apply(Geometry const& geometry, Collection& collection)
+ {
+ collection.push_back(geometry);
+ }
+};
+
+template<typename Geometry, typename Collection>
+inline void insert(Geometry const& geometry, Collection& collection)
+{
+ insert_geometry
+ <
+ typename geometry::tag<Geometry>::type,
+ typename geometry::tag
+ <
+ typename boost::range_value<Collection>::type
+ >::type
+ >::apply(geometry, collection);
+}
+
+}} // namespace detail::inserter
+
+
+
+namespace detail { namespace dissolver
+{
+
+class plusmin_policy
+{
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputCollection
+ >
+ static inline bool check_negative(Geometry1 a, Geometry2 b,
+ OutputCollection& output_collection)
+ {
+ // Precondition: a = positive, b = negative
+
+ // 1: make b positive to get proper intersection
+ geometry::reverse(b);
+ {
+ // 2: Check if there is overlap
+ OutputCollection difference;
+ geometry::intersection(a, b, difference);
+ if(difference.size() <= 0)
+ {
+ return false;
+ }
+ }
+
+ // There is overlap and we want to remove it, by subtracting it from b
+
+ //negative = true;
+
+ typedef typename geometry::point_type<Geometry2>::type point_type;
+ typedef overlay::turn_info<point_type> turn_info;
+ std::deque<turn_info> turns;
+
+ // Get (and stop on) any intersection
+ detail::disjoint::disjoint_interrupt_policy policy;
+ geometry::get_turns
+ <
+ false, false,
+ overlay::assign_null_policy
+ >(a, b, turns, policy);
+
+ if (! policy.has_intersections)
+ {
+ // There is overlap but no intersections -> b is inside a.
+ // So keep A and keep B, do not change anything
+ return false;
+ }
+
+ // There are intersections.
+ // 3: make a negative
+ geometry::reverse(a); // now negative
+
+ // This will calculate B minus A, result is then positive
+ OutputCollection difference;
+ geometry::intersection(a, b, difference);
+
+ // Add original a to output (NOT necessary! TODO avoid this)
+ {
+ geometry::reverse(a); // positive again
+ detail::inserter::insert(a, output_collection);
+ }
+
+
+ // Make negative output negative again
+ typedef typename boost::range_iterator<OutputCollection>::type iterator_type;
+ for(iterator_type it = boost::begin(difference);
+ it != boost::end(difference);
+ ++it)
+ {
+ geometry::reverse(*it);
+ detail::inserter::insert(*it, output_collection);
+ }
+ return true;
+ }
+
+
+public :
+
+ template
+ <
+ typename Geometry1,
+ typename Geometry2,
+ typename OutputCollection
+ >
+ static inline bool apply(Geometry1 const& a, Geometry2 const& b,
+ OutputCollection& output_collection)
+ {
+ typedef typename geometry::coordinate_type<Geometry2>::type coordinate_type;
+ coordinate_type area_a = geometry::area(a);
+ coordinate_type area_b = geometry::area(b);
+
+ // DEBUG
+ /*
+ int n = boost::size(output_collection);
+ typedef typename geometry::point_type<Geometry2>::type point_type;
+ std::cout << "Combine "
+ << area_a << " with " << " " << area_b
+ << " { " << geometry::wkt(geometry::return_centroid<point_type>(a))
+ << geometry::wkt(geometry::return_centroid<point_type>(b)) << " }"
+ << std::endl;
+ */
+ // END DEBUG
+
+ coordinate_type zero = coordinate_type();
+ if (area_a > zero && area_b > zero)
+ {
+ geometry::union_(a, b, output_collection);
+ return true;
+ }
+ else if (area_a > zero && area_b < zero)
+ {
+ return check_negative(a, b, output_collection);
+ }
+ else if (area_a < zero && area_b > zero)
+ {
+ return check_negative(b, a, output_collection);
+ }
+
+ // both negative (?) TODO
+ // DEBUG
+ /*
+ for (int i = n; i < boost::size(output_collection); i++)
+ {
+ typedef typename geometry::point_type<Geometry2>::type point_type;
+ std::cout << "Result "
+ << geometry::area(output_collection[i])
+ << " " << geometry::wkt(geometry::return_centroid<point_type>(output_collection[i]))
+ << std::endl;
+ }
+ */
+ // END DEBUG
+ return false;
+
+ }
+
+};
+
+
+template <typename CombinePolicy>
+struct dissolver_generic
+{
+
+
+ // Small structure to access elements by index;
+ // this avoids copying or accessing elements by address (pointer)
+ template <typename Box>
+ struct dissolve_helper
+ {
+ int source; // 0,1
+ int index; // index in the original array
+ bool dissolved;
+ Box box;
+ double area;
+
+ dissolve_helper()
+ {}
+
+ dissolve_helper(int i, Box b, double a, int s)
+ : source(s)
+ , index(i)
+ , dissolved(false)
+ , box(b)
+ , area(a)
+ {}
+ };
+
+
+ struct get_geometry
+ {
+ template <typename Range>
+ inline static typename boost::range_value<Range>::type const& apply(
+ Range const& range, int index)
+ {
+ return range[index];
+ }
+ };
+
+ template
+ <
+ typename Vector,
+ typename HelperVector
+ >
+ static inline void init_helper(Vector const& v, HelperVector& helper,
+ int index = 0, int source = 0)
+ {
+ typedef typename boost::range_value<Vector>::type value_type;
+ typedef typename geometry::point_type<value_type>::type point_type;
+ typedef model::box<point_type> box_type;
+ for(typename boost::range_iterator<Vector const>::type
+ it = boost::begin(v);
+ it != boost::end(v);
+ ++it, ++index)
+ {
+ helper.push_back(dissolve_helper<box_type>(index,
+ geometry::return_envelope<box_type>(*it),
+ geometry::area(*it),
+ source));
+ }
+ }
+
+ template
+ <
+ typename Element,
+ typename Geometry1, typename Geometry2,
+ typename OutputCollection
+ >
+ static inline bool call_policy(
+ Element const& element1, Element const& element2,
+ Geometry1 const& geometry1, Geometry2 const& geometry2
+ , OutputCollection& output_collection)
+ {
+ if (! geometry::disjoint(geometry1, geometry2))
+ {
+ /*std::cout << "Process " << element1.source << "/" << element1.index
+ << " and " << element2.source << "/" << element2.index
+ << " (" << element2.dissolved << "," << element2.dissolved << ")"
+ << std::endl;
+ */
+ return CombinePolicy::apply(geometry1, geometry2,
+ output_collection);
+ }
+ return false;
+ }
+
+
+ template
+ <
+ int Dimension,
+ typename HelperVector,
+ typename IndexVector,
+ typename InputRange,
+ typename OutputCollection,
+ typename Box
+ >
+ static inline bool divide_and_conquer(HelperVector& helper_vector
+ , IndexVector& index_vector
+ , InputRange const& input_range
+ , OutputCollection& output_collection
+ , Box const& total_box
+ , bool& changed
+ , int iteration = 0
+ )
+ {
+ //std::cout << "divide_and_conquer " << iteration << std::endl;
+ typedef typename geometry::coordinate_type<Box>::type coordinate_type;
+ typedef typename boost::range_value<HelperVector>::type helper_type;
+ typedef typename boost::range_iterator<IndexVector const>::type iterator_type;
+
+ //if (boost::size(index_vector) >= 16 && iteration < 100)
+ // Not yet using divide and conquer
+ if (false)
+ {
+ // 1: separate box into 2 (either horizontally or vertically)
+ Box lower_box = total_box, upper_box = total_box;
+ coordinate_type two = 2.0;
+ coordinate_type mid
+ = (geometry::get<min_corner, Dimension>(total_box)
+ + geometry::get<max_corner, Dimension>(total_box)) / two;
+
+ geometry::set<max_corner, Dimension>(lower_box, mid);
+ geometry::set<min_corner, Dimension>(upper_box, mid);
+
+ // 2: divide indices into two sublists
+ IndexVector lower_list, upper_list;
+ for(iterator_type it = boost::begin(index_vector);
+ it != boost::end(index_vector);
+ ++it)
+ {
+ helper_type const& element = helper_vector[*it];
+ if (! geometry::disjoint(lower_box, element.box))
+ {
+ lower_list.push_back(*it);
+ }
+ if (! geometry::disjoint(upper_box, element.box))
+ {
+ upper_list.push_back(*it);
+ }
+ }
+
+ //std::cout << lower_list.size() << ", " << upper_list.size()<< std::endl;
+
+ // 3: recursively call function (possibly divide in other dimension)
+ divide_and_conquer<1 - Dimension>(helper_vector,
+ lower_list, input_range, output_collection, lower_box, changed, iteration + 1);
+ divide_and_conquer<1 - Dimension>(helper_vector,
+ upper_list, input_range, output_collection, upper_box, changed, iteration + 1);
+ return changed;
+ }
+
+ // There are less then 16 elements, handle them quadraticly
+
+ int n = boost::size(output_collection);
+
+ for(iterator_type it1 = boost::begin(index_vector);
+ it1 != boost::end(index_vector);
+ ++it1)
+ {
+ helper_type& element1 = helper_vector[*it1];
+
+ bool unioned = false;
+ for(iterator_type it2 = boost::begin(index_vector);
+ ! unioned && it2 != it1;
+ ++it2)
+ {
+ helper_type& element2 = helper_vector[*it2];
+
+ // If they are NOT disjoint, union them
+ if (! element1.dissolved
+ && ! element2.dissolved
+ && ! geometry::disjoint(element1.box, element2.box))
+ {
+ // Runtime type check here...
+ if ((element1.source == 0 && element2.source == 0
+ && call_policy
+ (
+ element1, element2,
+ get_geometry::apply(input_range, element1.index),
+ get_geometry::apply(input_range, element2.index),
+ output_collection
+ )
+ )
+ || (element1.source == 0 && element2.source == 1
+ && call_policy
+ (
+ element1, element2,
+ get_geometry::apply(input_range, element1.index),
+ get_geometry::apply(output_collection, element2.index),
+ output_collection
+ )
+ )
+ || (element1.source == 1 && element2.source == 0
+ && call_policy
+ (
+ element1, element2,
+ get_geometry::apply(output_collection, element1.index),
+ get_geometry::apply(input_range, element2.index),
+ output_collection
+ )
+ )
+ || (element1.source == 1 && element2.source == 1
+ && call_policy
+ (
+ element1, element2,
+ get_geometry::apply(output_collection, element1.index),
+ get_geometry::apply(output_collection, element2.index),
+ output_collection
+ )
+ )
+ )
+ {
+ changed = true;
+ element1.dissolved = true;
+ element2.dissolved = true;
+
+ unioned = true;
+/*std::cout << "Assign " << element1.source << "/" << element1.index
+<< " and " << element2.source << "/" << element2.index
+<< " (" << element2.dissolved << "," << element2.dissolved << ")"
+<< std::endl;
+*/
+ }
+ }
+ }
+ }
+
+ // Append new records in output collection to helper class
+ init_helper(std::make_pair(boost::begin(output_collection) + n,
+ boost::end(output_collection)), helper_vector, n, 1);
+
+ return changed;
+ }
+
+ template <typename T>
+ static inline bool helper_dissolved(T const& t)
+ {
+ return t.dissolved;
+ }
+
+
+
+ template
+ <
+ typename InputRange,
+ typename OutputCollection
+ >
+ static inline void apply(InputRange const& input_range
+ , OutputCollection& output_collection
+ )
+ {
+ typedef typename boost::range_value<OutputCollection>::type output_type;
+
+ typedef typename geometry::point_type<output_type>::type point_type;
+ typedef model::box<point_type> box_type;
+ typedef dissolve_helper<box_type> dissolve_helper_type;
+ typedef std::vector<dissolve_helper_type> helper_vector_type;
+
+ // Vector with indices to both input_range (source 0) and output_collection (source 1)
+ helper_vector_type helper_vector;
+
+ // Vector with indices to helper-vector, for divide and conquer
+ std::vector<int> index_vector;
+
+
+ init_helper(input_range, helper_vector);
+
+ // Fill intrusive list with copies, and determine bounding box
+ box_type total_box;
+ geometry::assign_inverse(total_box);
+ int index = 0;
+ for(typename boost::range_iterator<helper_vector_type const>::type
+ it = boost::begin(helper_vector);
+ it != boost::end(helper_vector);
+ ++it, ++index)
+ {
+ index_vector.push_back(index);
+ geometry::expand(total_box, it->box);
+ }
+
+ std::vector<output_type> unioned_collection;
+
+ int size = 0, previous_size = 0;
+ int n = 0;
+
+ bool changed = false;
+ while(divide_and_conquer<1>
+ (helper_vector, index_vector, input_range, unioned_collection, total_box, changed) && n < 5)
+ {
+ // Remove everything which is already dissolved.
+ helper_vector.erase
+ (
+ std::remove_if
+ (
+ helper_vector.begin(),
+ helper_vector.end(),
+ helper_dissolved<dissolve_helper_type>
+ ),
+ helper_vector.end()
+ );
+
+ previous_size = size;
+ size = helper_vector.size();
+ n = previous_size == size ? n + 1 : 0;
+
+ // Re-initialize the list
+ index_vector.clear();
+ int index = 0;
+ for(typename boost::range_iterator<helper_vector_type const>::type
+ it = boost::begin(helper_vector);
+ it != boost::end(helper_vector);
+ ++it, ++index)
+ {
+ index_vector.push_back(index);
+ }
+
+ changed = false;
+
+ //std::cout << " " << size;
+ }
+
+ // Add input+output to real output
+ typedef typename boost::range_iterator<helper_vector_type>::type iterator_type;
+ for(iterator_type it = boost::begin(helper_vector);
+ it != boost::end(helper_vector);
+ ++it)
+ {
+ if (! it->dissolved)
+ {
+ switch(it->source)
+ {
+ case 0 :
+ detail::inserter::insert(
+ get_geometry::apply(input_range, it->index),
+ output_collection);
+ break;
+ case 1 :
+ detail::inserter::insert(
+ get_geometry::apply(unioned_collection, it->index),
+ output_collection);
+ break;
+ }
+ }
+ }
+ }
+};
+
+
+}} // namespace detail::dissolver
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryTag1,
+ typename GeometryTag2,
+ typename Policy
+>
+struct dissolver
+{};
+
+
+template<typename Policy>
+struct dissolver<ring_tag, polygon_tag, Policy>
+ : detail::dissolver::dissolver_generic<Policy>
+{};
+
+template<typename Policy>
+struct dissolver<polygon_tag, polygon_tag, Policy>
+ : detail::dissolver::dissolver_generic<Policy>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template
+<
+ typename InputRange,
+ typename OutputCollection
+>
+inline void dissolver(InputRange const& input_range,
+ OutputCollection& output_collection)
+{
+ typedef typename boost::range_value<InputRange>::type geometry_in;
+ typedef typename boost::range_value<OutputCollection>::type geometry_out;
+ concept::check<geometry_in const>();
+ concept::check<geometry_out>();
+
+ dispatch::dissolver
+ <
+ typename tag<geometry_in>::type,
+ typename tag<geometry_out>::type,
+ detail::dissolver::plusmin_policy
+ >::apply(input_range, output_collection);
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DETAIL_OVERLAY_DISSOLVER_HPP
diff --git a/src/boost/geometry/extensions/algorithms/detail/overlay/msm_state.hpp b/src/boost/geometry/extensions/algorithms/detail/overlay/msm_state.hpp
new file mode 100644
index 0000000..1cff563
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/detail/overlay/msm_state.hpp
@@ -0,0 +1,187 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_MSM_STATE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_MSM_STATE_HPP
+
+
+
+#ifdef USE_MSM_MINI
+
+# include <boost/msm/back/mini_state_machine.hpp>
+# include <boost/fusion/include/vector.hpp>
+
+#else
+
+# include <boost/msm/back/state_machine.hpp>
+# include <boost/msm/front/state_machine_def.hpp>
+
+#endif
+
+
+
+// Events
+struct starting {};
+struct visit {};
+struct finish {};
+
+
+// Flags
+struct is_init {};
+struct is_visited {};
+
+enum StatesEnum
+{
+ STATE_NONE=0,
+ STATE_IS_INIT=1,
+ STATE_IS_VISITED=2
+};
+
+
+
+#ifndef USE_MSM_MINI
+
+// front-end: define the FSM structure
+struct traverse_state_ : public boost::msm::front::state_machine_def<traverse_state_>
+{
+ traverse_state_():m_state(STATE_IS_INIT){}
+ // The list of FSM states
+ struct Init : public boost::msm::front::state<>
+ {
+ typedef boost::mpl::vector1<is_init> flag_list;
+ //template <class Event,class FSM>
+ //void on_entry(Event const&,FSM& fsm) {fsm.m_state=STATE_IS_INIT;}
+ };
+
+ struct Started : public boost::msm::front::state<>
+ {
+ //template <class Event,class FSM>
+ //void on_entry(Event const&,FSM& fsm) {fsm.m_state=STATE_NONE;}
+ };
+
+ struct Visited : public boost::msm::front::state<>
+ {
+ typedef boost::mpl::vector1<is_visited> flag_list;
+ //template <class Event,class FSM>
+ //void on_entry(Event const&,FSM& fsm) {fsm.m_state=STATE_IS_VISITED;}
+ };
+
+ struct Finished : public boost::msm::front::state<>
+ {
+ typedef boost::mpl::vector1<is_visited> flag_list;
+ //template <class Event,class FSM>
+ //void on_entry(Event const&,FSM& fsm) {fsm.m_state=STATE_IS_VISITED;}
+ };
+
+
+ // the initial state of the player SM. Must be defined
+ typedef Init initial_state;
+
+ // transition actions
+ void start_traverse(starting const&) {m_state=STATE_NONE;}
+ void finish_after_visit(finish const&) {m_state=STATE_IS_VISITED;}
+ void do_finish(finish const&) {m_state=STATE_IS_VISITED;}
+ void do_visit(visit const&) {m_state=STATE_IS_VISITED;}
+ void do_visit2(visit const&) {m_state=STATE_IS_VISITED;}
+ void do_nothing(finish const&) {m_state=STATE_IS_VISITED;}
+
+
+ typedef traverse_state_ p; // makes transition table cleaner
+
+ // Transition table for player
+ struct transition_table : mpl::vector
+ <
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Init , starting , Started , &p::start_traverse >,
+ a_row < Init , visit , Visited , &p::do_visit >,
+ a_row < Init , finish , Finished , &p::do_nothing >,
+ a_row < Started , finish , Finished , &p::do_finish >,
+ a_row < Started , visit , Visited , &p::do_visit2 >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Visited , finish , Finished , &p::finish_after_visit >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+
+ // Replaces the default no-transition response.
+ template <class Machine, class Event>
+ void no_transition(Event const& e, Machine&, int state)
+ {
+ //std::cout << "no transition from state " << state << " on event " << typeid(e).name() << std::endl;
+ }
+
+ typedef int no_exception_thrown;
+ typedef int no_message_queue;
+ StatesEnum m_state;
+
+};
+
+
+typedef boost::msm::back::state_machine<traverse_state_> traverse_state;
+
+#else
+
+// mini-back-end
+
+
+struct traverse_state : public boost::msm::back::mini::state_machine<traverse_state>
+{
+ traverse_state():m_state(STATE_IS_INIT){}
+
+ // The list of FSM states
+ enum states
+ {
+ Init, Started, Visited, Finished
+ , initial_state = Init
+ };
+
+ friend class boost::msm::back::mini::state_machine<traverse_state>;
+ typedef traverse_state p; // makes transition table cleaner
+
+ // transition actions
+ void start_traverse(starting const&) {m_state=STATE_NONE;}
+ void finish_after_visit(finish const&) {m_state=STATE_IS_VISITED;}
+ void do_finish(finish const&) {m_state=STATE_IS_VISITED;}
+ void do_visit(visit const&) {m_state=STATE_IS_VISITED;}
+ void do_visit2(visit const&) {m_state=STATE_IS_VISITED;}
+ void do_nothing(finish const&) {m_state=STATE_IS_VISITED;}
+
+ bool flag_none() const { return m_state == STATE_IS_INIT; }
+ bool flag_visited() const { return m_state == STATE_IS_VISITED; }
+
+
+ // Transition table
+ struct transition_table : mpl::vector6<
+ // Start Event Next Action
+ // +---------+-------------+---------+---------------------+
+ row < Init , starting , Started , &p::start_traverse >,
+ row < Init , visit , Visited , &p::do_visit >,
+ row < Init , finish , Finished, &p::do_nothing >,
+ row < Started , finish , Finished, &p::do_finish >,
+ row < Started , visit , Visited , &p::do_visit2 >,
+ row < Visited , finish , Finished, &p::finish_after_visit>
+ // +---------+-------------+---------+---------------------+
+ > {};
+
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& e)
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(e).name() << std::endl;
+ return state;
+ }
+ StatesEnum m_state;
+
+};
+
+#endif
+
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_MSM_STATE_HPP
diff --git a/src/boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp b/src/boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp
new file mode 100644
index 0000000..af8e0f8
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/detail/overlay/split_rings.hpp
@@ -0,0 +1,547 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DETAIL_OVERLAY_SPLIT_RINGS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DETAIL_OVERLAY_SPLIT_RINGS_HPP
+
+#define BOOST_GEOMETRY_CHECK_SPLIT_RINGS
+
+#include <deque>
+#include <string>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#if defined(BOOST_GEOMETRY_DEBUG_SPLIT_RINGS) || defined(BOOST_GEOMETRY_CHECK_SPLIT_RINGS)
+# include <boost/geometry/io/wkt/wkt.hpp>
+#endif
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace split_rings
+{
+
+template <typename Range>
+struct split_range
+{
+/*
+
+ 1 2
+ +-------------+
+ | 4 /
+ | |\ /
+ | | \/____ IP
+ | | /\
+ | |/ \
+ | 3 \
+ +-------------+
+ 0,6 5
+
+ - we want to split the range at the IP into two rings
+ - At the IP: we have segment_indices 2,4 (result of get_turns_in_sections)
+ - We want to copy and remove vertices 3,4
+ --> count=4-2
+ --> copy [3,5) -> copy(begin()+id1+1, begin()+id1+count+1)
+ --> erase: idem
+ --> insert(begin()+id1+1)
+
+ --> we use id1+1
+
+ After that, we need to update all indices AFTER IP.
+ We removed two vertices here (4-2), and added one (the IP)
+
+*/
+ static inline void apply(Range& range, Range& output
+ , segment_identifier const& id1
+ , segment_identifier const& id2
+ , typename geometry::point_type<Range>::type const& point
+ )
+ {
+ if (id1.ring_index == id2.ring_index
+ && id1.multi_index == id2.multi_index)
+ {
+ int mn = (std::min)(id1.segment_index, id2.segment_index);
+ mn++;
+
+ typename boost::range_iterator<Range>::type first = range.begin();
+ first += mn;
+
+ typename boost::range_iterator<Range>::type last = first;
+ last += geometry::math::abs(id2.segment_index - id1.segment_index);
+
+ // Create splitted ring
+ output.push_back(point);
+ std::copy(first, last, std::back_inserter(output));
+ output.push_back(point);
+
+ // Remove the loop from the range
+ range.erase(first, last);
+
+ // Iterator is invalid because of erasure, construct again
+ range.insert(range.begin() + mn, point);
+ }
+ }
+};
+
+
+/*template <typename Polygon>
+struct split_polygon
+{
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ static inline void apply(Polygon& polygon, ring_type& splitted
+ , segment_identifier const& id1
+ , segment_identifier const& id2
+ , typename geometry::point_type<Polygon>::type const& point
+ )
+ {
+ if (id1.ring_index == id2.ring_index
+ && id1.multi_index == id2.multi_index)
+ {
+ ring_type& ring = id1.ring_index < 0
+ ? geometry::exterior_ring(polygon)
+ : geometry::interior_rings(polygon)[id1.ring_index];
+
+ split_range<ring_type>::apply(ring, splitted, id1, id2, point);
+ }
+ }
+};*/
+
+
+template <typename Tag, typename Geometry>
+struct split
+{};
+
+
+template <typename Ring>
+struct split<ring_tag, Ring> : split_range<Ring>
+{};
+
+
+//template <typename Polygon>
+//struct split<polygon_tag, Polygon> : split_polygon<Polygon>
+//{};
+
+
+
+
+
+
+template <typename Tag, typename RingCollection, typename Geometry>
+struct insert_rings
+{};
+
+
+template <typename RingCollection, typename Ring>
+struct insert_rings<ring_tag, RingCollection, Ring>
+{
+ static inline void apply(RingCollection& ring_collection, Ring const& ring)
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_SPLIT_RINGS
+std::cout << geometry::wkt(ring)
+ << " ; " << geometry::area(ring)
+ << " " << ring.size()
+ //<< " at " << geometry::wkt(first.point)
+ << std::endl;
+/*std::cout << "geometry "
+ << " " << geometry::area(geometry)
+ << std::endl;*/
+#endif
+
+ ring_collection.push_back(ring);
+ }
+};
+
+
+template <typename RingCollection, typename Polygon>
+struct insert_rings<polygon_tag, RingCollection, Polygon>
+{
+ static inline void apply(RingCollection& ring_collection, Polygon const& polygon)
+ {
+ ring_collection.push_back(exterior_ring(polygon));
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+#ifdef BOOST_GEOMETRY_DEBUG_SPLIT_RINGS
+std::cout << geometry::wkt(*it)
+ << " ; " << geometry::area(*it)
+ << " " << it->size()
+ //<< " at " << geometry::wkt(first.point)
+ << std::endl;
+/*std::cout << "geometry "
+ << " " << geometry::area(geometry)
+ << std::endl;*/
+#endif
+
+ ring_collection.push_back(*it);
+ }
+ }
+};
+
+
+/// Sorts vector of turns (results from get_turns)
+template <typename Turn>
+struct sorter
+{
+ inline bool operator()(Turn const& left, Turn const& right) const
+ {
+ if (left.count_between != right.count_between)
+ {
+ return left.count_between < right.count_between;
+ }
+
+ if (left.operations[0].seg_id.segment_index
+ == right.operations[0].seg_id.segment_index)
+ {
+ return left.operations[0].distance < right.operations[0].distance;
+ }
+ return left.operations[0].seg_id.segment_index
+ < right.operations[0].seg_id.segment_index;
+ }
+};
+
+/// Turn operation with additional distance field
+template <typename P>
+struct split_turn_operation : public detail::overlay::turn_operation
+{
+ inline split_turn_operation()
+ : detail::overlay::turn_operation()
+ , distance(geometry::return_distance_result<distance_type>(0))
+ {}
+
+ typedef typename default_distance_result<P, P>::type distance_type;
+ distance_type distance; // distance-measurement from segment.first to IP
+};
+
+
+/// Turn information with distance fields, plus "count_between" field
+template <typename P>
+struct split_turn_info : detail::overlay::turn_info
+ <
+ P, split_turn_operation<P>
+ >
+{
+ //std::string history;
+ int count_between; // counts number of segments between ring in intersection
+
+ split_turn_info()
+ : count_between(0)
+ {}
+};
+
+
+/// Policy to calculate distance
+struct split_calculate_distance_policy
+{
+ template <typename Point1, typename Point2, typename Info>
+ static inline void apply(Info& info, Point1 const& p1, Point2 const& p2)
+ {
+ info.operations[0].distance
+ = geometry::distance(info.point, p1);
+ info.operations[1].distance
+ = geometry::distance(info.point, p2);
+ }
+
+};
+
+
+template <typename Range, typename RingCollection>
+class range_split_rings
+{
+ typedef typename geometry::tag<Range>::type tag;
+ typedef typename geometry::point_type<Range>::type point_type;
+
+ typedef typename geometry::ring_type<Range>::type ring_type;
+
+
+ typedef typename strategy_intersection
+ <
+ typename cs_tag<point_type>::type,
+ point_type,
+ point_type,
+ point_type
+ >::segment_intersection_strategy_type strategy;
+
+
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_SPLIT_RINGS
+ template <typename Turns>
+ static void report(Turns const& turns, std::string const& header)
+ {
+ if (turns.empty())
+ {
+ return;
+ }
+ std::cout << header << std::endl;
+ BOOST_FOREACH(typename boost::range_value<Turns>::type const& turn, turns)
+ {
+ std::cout
+ << "I at " << turn.operations[0].seg_id.segment_index
+ << "/" << turn.operations[1].seg_id.segment_index
+ << " (" << turn.count_between
+ << ") " << turn.operations[0].distance
+ << "/" << turn.operations[1].distance
+ << " " << geometry::wkt(turn.point) << std::endl;
+ }
+ }
+#endif
+
+ template <typename Operation>
+ static bool adapt(Operation& op, Operation const& first, Operation const& second)
+ {
+ if (first.seg_id.segment_index > second.seg_id.segment_index)
+ {
+ return adapt(op, second, first);
+ }
+ if (op.seg_id.segment_index > first.seg_id.segment_index
+ || (op.seg_id.segment_index == first.seg_id.segment_index
+ && op.distance > first.distance)
+ )
+ {
+ if (op.seg_id.segment_index < second.seg_id.segment_index
+ || (op.seg_id.segment_index == second.seg_id.segment_index
+ && op.distance < second.distance)
+ )
+ {
+ // mark for deletion
+ op.seg_id.segment_index = -1;
+ return true;
+ }
+ else
+ {
+ op.seg_id.segment_index -= (second.seg_id.segment_index - first.seg_id.segment_index - 1);
+ }
+ }
+ return false;
+ }
+
+
+ static void call(Range range, RingCollection& ring_collection)
+ {
+ typedef split_turn_info<point_type> turn_info;
+
+ typedef std::deque<turn_info> turns_type;
+ turns_type turns;
+
+ detail::get_turns::no_interrupt_policy policy;
+ geometry::get_turns
+ <
+ split_calculate_distance_policy
+ >(range, turns, policy);
+
+ //report(turns, "intersected");
+
+ // Make operations[0].seg_id always the smallest, to sort properly
+ // Also calculate the number of segments in between
+ for (typename boost::range_iterator<turns_type>::type
+ it = boost::begin(turns);
+ it != boost::end(turns);
+ ++it)
+ {
+ turn_info& turn = *it;
+ if (turn.operations[0].seg_id.segment_index > turn.operations[1].seg_id.segment_index)
+ {
+ std::swap(turn.operations[0], turn.operations[1]);
+ }
+ // ...[1] > ...[0]
+ // check count
+ int const between1 = turn.operations[1].seg_id.segment_index
+ - turn.operations[0].seg_id.segment_index;
+ /*
+ NOTE: if we would use between2 here, we have to adapt other code as well,
+ such as adaption of the indexes; splitting of the range, etc.
+ int between2 = boost::size(range) + turn.operations[0].seg_id.segment_index
+ - turn.operations[1].seg_id.segment_index;
+ turn.count_between = (std::min)(between1, between2);
+ */
+
+ turn.count_between = between1;
+ }
+ //report(turns, "swapped");
+
+ std::sort(turns.begin(), turns.end(), sorter<turn_info>());
+ //report(turns, "sorted");
+
+ while(turns.size() > 0)
+ {
+ // Process first turn
+ turn_info const& turn = turns.front();
+
+ split_turn_operation<point_type> const& first_op = turn.operations[0];
+ split_turn_operation<point_type> const& second_op = turn.operations[1];
+ bool do_split = first_op.seg_id.segment_index >= 0
+ && second_op.seg_id.segment_index >= 0;
+
+ if (do_split)
+ {
+#ifdef BOOST_GEOMETRY_CHECK_SPLIT_RINGS
+ ring_type copy = range; // TEMP, for check
+#endif
+ ring_collection.resize(ring_collection.size() + 1);
+ split<ring_tag, Range>::apply(range, ring_collection.back(),
+ turn.operations[0].seg_id, turn.operations[1].seg_id,
+ turn.point);
+
+#ifdef BOOST_GEOMETRY_CHECK_SPLIT_RINGS
+ {
+ std::deque<turn_info> splitted_turns;
+ geometry::get_turns
+ <
+ split_calculate_distance_policy
+ >(ring_collection.back(),
+ splitted_turns,
+ detail::get_turns::no_interrupt_policy());
+
+ if (splitted_turns.size() > 0)
+ {
+ std::cout << "TODO Still intersecting! " << splitted_turns.size() << std::endl;
+ //std::cout << " " << geometry::wkt(copy) << std::endl;
+ //std::cout << " " << geometry::wkt(splitted) << std::endl;
+ //report(splitted_turns, "NOT OK");
+ //std::cout << std::endl;
+ }
+ }
+#endif
+
+ }
+
+ turns.pop_front();
+
+
+ if (do_split)
+ {
+ for (typename boost::range_iterator<turns_type>::type
+ rest = boost::begin(turns);
+ rest != boost::end(turns);
+ ++rest)
+ {
+ //turn_info copy = turn;
+ if (adapt(rest->operations[0], first_op, second_op)
+ || adapt(rest->operations[1], first_op, second_op))
+ {
+ /**
+ std::cout << " ADAPTED "
+ << copy.operations[0].seg_id.segment_index << "/" << copy.operations[1].seg_id.segment_index
+ << " "
+ << geometry::wkt(copy.point) << std::endl;
+ **/
+ }
+ }
+ }
+ while(turns.size() > 0
+ && (turns.front().operations[0].seg_id.segment_index < 0
+ || turns.front().operations[1].seg_id.segment_index < 0))
+ {
+ turns.pop_front();
+ }
+ }
+
+ // Add the (possibly untouched) input range
+ insert_rings<ring_tag, RingCollection, Range>::apply(ring_collection, range);
+ }
+
+public :
+ // Copy by value of range is intentional, copy is modified here
+ static inline void apply(Range range, RingCollection& ring_collection)
+ {
+ call(range, ring_collection);
+ }
+};
+
+template <typename Polygon, typename RingCollection>
+struct polygon_split_rings
+{
+ typedef range_split_rings
+ <
+ typename ring_type<Polygon>::type,
+ RingCollection
+ > per_ring;
+
+ static inline void apply(Polygon const& polygon, RingCollection& ring_collection)
+ {
+ per_ring::apply(exterior_ring(polygon), ring_collection);
+ for (BOOST_AUTO_TPL(it, boost::begin(interior_rings(polygon)));
+ it != boost::end(interior_rings(polygon));
+ ++it)
+ {
+ per_ring::apply(*it, ring_collection);
+ }
+ }
+};
+
+
+}} // namespace detail::split_rings
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryTag,
+ typename Geometry,
+ typename RingCollection
+>
+struct split_rings
+{};
+
+
+template<typename Polygon, typename RingCollection>
+struct split_rings<polygon_tag, Polygon, RingCollection>
+ : detail::split_rings::polygon_split_rings<Polygon, RingCollection>
+{};
+
+
+template<typename Ring, typename RingCollection>
+struct split_rings<ring_tag, Ring, RingCollection>
+ : detail::split_rings::range_split_rings<Ring, RingCollection>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template
+<
+ typename Geometry,
+ typename RingCollection
+>
+inline void split_rings(Geometry const& geometry, RingCollection& out)
+{
+ concept::check<Geometry const>();
+ concept::check<typename boost::range_value<RingCollection>::type>();
+
+ dispatch::split_rings
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ RingCollection
+ >::apply(geometry, out);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DETAIL_OVERLAY_SPLIT_RINGS_HPP
diff --git a/src/boost/geometry/extensions/algorithms/dissolve.hpp b/src/boost/geometry/extensions/algorithms/dissolve.hpp
new file mode 100644
index 0000000..94be38e
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/dissolve.hpp
@@ -0,0 +1,293 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DISSOLVE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DISSOLVE_HPP
+
+
+#include <map>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp>
+
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp>
+#include <boost/geometry/algorithms/detail/overlay/traverse.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/add_rings.hpp>
+#include <boost/geometry/algorithms/detail/overlay/assign_parents.hpp>
+#include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
+#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dissolve
+{
+
+struct no_interrupt_policy
+{
+ static bool const enabled = false;
+ static bool const has_intersections = false;
+
+
+ template <typename Range>
+ static inline bool apply(Range const&)
+ {
+ return false;
+ }
+};
+
+
+template<typename Geometry>
+class backtrack_for_dissolve
+{
+public :
+ typedef detail::overlay::backtrack_state state_type;
+
+ template <typename Operation, typename Rings, typename Turns>
+ static inline void apply(std::size_t size_at_start,
+ Rings& rings, typename boost::range_value<Rings>::type& ring,
+ Turns& turns, Operation& operation,
+ std::string const& ,
+ Geometry const& ,
+ Geometry const& ,
+ state_type& state
+ )
+ {
+ state.m_good = false;
+
+ // Make bad output clean
+ rings.resize(size_at_start);
+ ring.clear();
+
+ // Reject this as a starting point
+ operation.visited.set_rejected();
+
+ // And clear all visit info
+ clear_visit_info(turns);
+ }
+};
+
+
+template <typename Geometry, typename GeometryOut>
+struct dissolve_ring_or_polygon
+{
+ template <typename OutputIterator>
+ static inline OutputIterator apply(Geometry const& geometry,
+ OutputIterator out)
+ {
+ // Get the self-intersection points, including turns
+ typedef detail::overlay::traversal_turn_info
+ <
+ typename point_type<Geometry>::type
+ > turn_info;
+
+ std::vector<turn_info> turns;
+ detail::dissolve::no_interrupt_policy policy;
+ geometry::self_turns
+ <
+ detail::overlay::calculate_distance_policy
+ >(geometry, turns, policy);
+
+ // The dissolve process is not necessary if there are no turns at all
+
+ if (boost::size(turns) > 0)
+ {
+ typedef typename ring_type<Geometry>::type ring_type;
+ typedef std::vector<ring_type> out_vector;
+ out_vector rings;
+
+ // Enrich the turns
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Geometry>::type
+ >::type side_strategy_type;
+
+ enrich_intersection_points<false, false>(turns,
+ detail::overlay::operation_union,
+ geometry, geometry,
+ side_strategy_type());
+
+ typedef detail::overlay::traverse
+ <
+ false, false,
+ Geometry, Geometry,
+ backtrack_for_dissolve<Geometry>
+ > traverser;
+
+
+ // Traverse the polygons twice for union...
+ traverser::apply(geometry, geometry,
+ detail::overlay::operation_union,
+ turns, rings);
+
+ clear_visit_info(turns);
+
+ enrich_intersection_points<false, false>(turns,
+ detail::overlay::operation_intersection,
+ geometry, geometry,
+ side_strategy_type());
+
+
+ // ... and for intersection
+ traverser::apply(geometry, geometry,
+ detail::overlay::operation_intersection,
+ turns, rings);
+
+ std::map<ring_identifier, int> map;
+ map_turns(map, turns);
+
+ typedef detail::overlay::ring_properties<typename geometry::point_type<Geometry>::type> properties;
+
+ std::map<ring_identifier, properties> selected;
+
+ detail::overlay::select_rings<overlay_union>(geometry, map, selected, true);
+
+ // Add intersected rings
+ {
+ ring_identifier id(2, 0, -1);
+ for (typename boost::range_iterator<std::vector<ring_type> const>::type
+ it = boost::begin(rings);
+ it != boost::end(rings);
+ ++it)
+ {
+ selected[id] = properties(*it, true);
+ id.multi_index++;
+ }
+ }
+
+ detail::overlay::assign_parents(geometry, rings, selected);
+ return detail::overlay::add_rings<GeometryOut>(selected, geometry, rings, out);
+
+ }
+ else
+ {
+ GeometryOut g;
+ geometry::convert(geometry, g);
+ *out++ = g;
+ return out;
+ }
+ }
+};
+
+
+
+}} // namespace detail::dissolve
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryTag,
+ typename GeometryOutTag,
+ typename Geometry,
+ typename GeometryOut
+>
+struct dissolve
+{};
+
+
+template<typename Polygon, typename PolygonOut>
+struct dissolve<polygon_tag, polygon_tag, Polygon, PolygonOut>
+ : detail::dissolve::dissolve_ring_or_polygon<Polygon, PolygonOut>
+{};
+
+
+template<typename Ring, typename RingOut>
+struct dissolve<ring_tag, ring_tag, Ring, RingOut>
+ : detail::dissolve::dissolve_ring_or_polygon<Ring, RingOut>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+ \brief Removes self intersections from a geometry
+ \ingroup overlay
+ \tparam Geometry geometry type
+ \tparam OutputIterator type of intersection container
+ (e.g. vector of "intersection/turn point"'s)
+ \param geometry first geometry
+ \param out output iterator getting dissolved geometry
+ \note Currently dissolve with a (multi)linestring does NOT remove internal
+ overlap, it only tries to connect multiple line end-points.
+ TODO: we should change this behaviour and add a separate "connect"
+ algorithm, and let dissolve work like polygon.
+ */
+template
+<
+ typename GeometryOut,
+ typename Geometry,
+ typename OutputIterator
+>
+inline OutputIterator dissolve_inserter(Geometry const& geometry, OutputIterator out)
+{
+ concept::check<Geometry const>();
+ concept::check<GeometryOut>();
+
+ return dispatch::dissolve
+ <
+ typename tag<Geometry>::type,
+ typename tag<GeometryOut>::type,
+ Geometry,
+ GeometryOut
+ >::apply(geometry, out);
+}
+
+
+template
+<
+ typename Geometry,
+ typename Collection
+>
+inline void dissolve(Geometry const& geometry, Collection& output_collection)
+{
+ concept::check<Geometry const>();
+
+ typedef typename boost::range_value<Collection>::type geometry_out;
+
+ concept::check<geometry_out>();
+
+ dispatch::dissolve
+ <
+ typename tag<Geometry>::type,
+ typename tag<geometry_out>::type,
+ Geometry,
+ geometry_out
+ >::apply(geometry, std::back_inserter(output_collection));
+}
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DISSOLVE_HPP
diff --git a/src/boost/geometry/extensions/algorithms/mark_spikes.hpp b/src/boost/geometry/extensions/algorithms/mark_spikes.hpp
new file mode 100644
index 0000000..f1c0a3c
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/mark_spikes.hpp
@@ -0,0 +1,516 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_MARK_SPIKES_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_MARK_SPIKES_HPP
+
+#include <algorithm>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
+#include <boost/geometry/strategies/cartesian/area_surveyor.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/buffer.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/perimeter.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+
+
+/*
+Mark spikes in a ring/polygon.
+Ring
++---------+
+| |
+| |
+| +===== ^this "indentation" or "intrusion" or "spikey feature" is marked
+| || |
+| || |
+| ++ |
++---------+
+(the actualy determination if it is marked is done by a policy)
+(things are only marked, removal is done afterwards)
+
+*/
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace mark_spikes
+{
+
+template <typename Range, typename Iterator>
+inline Iterator circular_next(Range const& range, Iterator it)
+{
+ ++it;
+ if (it == boost::end(range))
+ {
+ it = boost::begin(range);
+ }
+ return it;
+}
+
+inline std::size_t circular_next_i(std::size_t i, std::size_t const n)
+{
+ if (++i == n)
+ {
+ i = 0;
+ }
+ return i;
+}
+
+
+// Calculate the distance over the ring, in the range [it1 .. it2]
+// if it1 < it2: walk from it1 .. it2
+// if it1 > it2: walk from it1 .. end(ring) and from begin(ring) to it2
+// Do NOT call this using begin(ring), end(ring) or 0.0 will be returned
+template
+<
+ typename Range,
+ typename Iterator,
+ typename AreaStrategy,
+ typename DistanceStrategy
+>
+inline void part_area_and_perimeter(Range const& range,
+ Iterator it1, Iterator it2,
+ AreaStrategy const& area_strategy,
+ DistanceStrategy const& distance_strategy,
+ double& area, double& perimeter, int& count)
+{
+ perimeter = 0;
+ area = 0;
+ count = 0;
+ if (it1 == boost::end(range) || it2 == boost::end(range) || it1 == it2)
+ {
+ return;
+ }
+
+ typename AreaStrategy::state_type area_state;
+ Iterator it = circular_next(range, it1), previous = it1;
+ Iterator end = circular_next(range, it2);
+ while (it != end)
+ {
+ area_strategy.apply(*previous, *it, area_state);
+ perimeter += distance_strategy.apply(*previous, *it);
+ previous = it;
+ it = circular_next(range, it);
+ count++;
+ }
+
+ // Close the ring, for area
+ area_strategy.apply(*it2, *it1, area_state);
+ // Do the same for distance to get correct ratio (though this might be discussed)
+ perimeter += distance_strategy.apply(*it2, *it1);
+
+ area = abs(area_strategy.result(area_state));
+}
+
+
+template <typename Iterator>
+struct helper
+{
+ helper(int i1, int i2, Iterator t1, Iterator t2,
+ double g, double a, double p, int c)
+ : index1(i1)
+ , index2(i2)
+ , it1(t1)
+ , it2(t2)
+ , gap_distance(g)
+ , area(a)
+ , perimeter(p)
+ , count(c)
+ {
+ }
+
+ int index1, index2;
+ Iterator it1, it2;
+ double area, perimeter, gap_distance;
+ int count;
+
+ inline bool operator<(helper<Iterator> const& other) const
+ {
+ return this->count > other.count;
+ }
+};
+
+
+template <typename Range, typename MarkMap, typename Policy>
+struct range_mark_spikes
+{
+ typedef typename point_type<Range>::type point_type;
+
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Range>::type
+ >::type side_strategy_type;
+
+ typedef typename strategy::area::services::default_strategy
+ <
+ typename cs_tag<point_type>::type,
+ point_type
+ >::type area_strategy_type;
+
+ typedef typename strategy::distance::services::default_strategy
+ <
+ point_tag,
+ point_type,
+ point_type
+ >::type distance_strategy_type;
+
+ static inline void apply(Range const& range, ring_identifier id,
+ MarkMap& mark_map, Policy const& policy)
+ {
+ std::size_t const n = boost::size(range);
+ if (n < 5)
+ {
+ return;
+ }
+
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ // Divide polygon in monotonic sections (in two directions)
+ typedef model::box<point_type> box_type;
+ typedef geometry::sections<box_type, 2> sections_type;
+ sections_type sections;
+ geometry::sectionalize<false>(range, sections);
+
+ for (typename boost::range_iterator<sections_type>::type it = boost::begin(sections);
+ it != boost::end(sections);
+ ++it)
+ {
+ // Enlarge each box with the wished max with of the gap to be sure that
+ // when walking through sections all point-pairs are considered
+ geometry::buffer(it->bounding_box, it->bounding_box, policy.gap_width() * 1.001);
+ }
+
+ double const whole_area = geometry::area(range);
+
+
+ typedef typename boost::range_iterator<sections_type>::type section_iterator_type;
+
+
+ // Find pair-of-points lying the most close to each other,
+ // where:
+ // - it is in another section
+ // - the distance over the ring-part is larger than X
+ // - the area of the polygon formed by that ring-part smaller than X
+
+ typedef helper<iterator_type> helper_type;
+ typedef std::vector<helper_type> helper_vector_type;
+ helper_vector_type candidates;
+
+ // Quadratic loop over all sections (note this normally does not result in a quadratic loop
+ // over all points).
+ for(section_iterator_type sit1 = boost::begin(sections); sit1 != boost::end(sections); ++sit1)
+ {
+ // Note, even though combination sit1/sit2 is handled, the combination sit2/sit1 travels
+ // another part over the ring and should be handled as well
+ for(section_iterator_type sit2 = boost::begin(sections); sit2 != boost::end(sections); ++sit2)
+ {
+ if (sit1->id != sit2->id
+ && ! geometry::disjoint(sit1->bounding_box, sit2->bounding_box))
+ {
+ // Check all point combinations in these boxes
+ int index1 = sit1->begin_index;
+ iterator_type it1 = boost::begin(range) + sit1->begin_index;
+ for (unsigned int i = 0; i < sit1->count; i++, ++it1, ++index1)
+ {
+ iterator_type it2 = boost::begin(range) + sit2->begin_index;
+ int index2 = sit2->begin_index;
+ for (unsigned int j = 0; j < sit2->count; j++, ++it2, ++index2)
+ {
+ double dg = geometry::distance(*it1, *it2);
+ if (dg < policy.gap_width())
+ {
+ double area, perimeter;
+ int count;
+ part_area_and_perimeter(range, it1, it2,
+ area_strategy_type(), distance_strategy_type(),
+ area, perimeter, count);
+
+ if (count >= 2
+ && policy.apply(dg, whole_area, count, area, perimeter))
+ {
+ candidates.push_back(
+ helper_type(index1, index2, it1, it2, dg, area, perimeter, count));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (boost::size(candidates) == 0)
+ {
+ return;
+ }
+
+ std::sort(candidates.begin(), candidates.end());
+
+ /***
+ if (boost::size(candidates) > 1)
+ {
+
+ // Remove overlaps
+ bool first = true;
+ typename boost::range_iterator<helper_vector_type>::type it = boost::begin(candidates);
+ typename boost::range_iterator<helper_vector_type>::type prev = it;
+ ++it;
+ while (it != boost::end(candidates))
+ {
+
+ if ((it->index1 >= prev->index1 && it->index2 <= prev->index2)
+
+ )
+ {
+ candidates.erase(it);
+ it = prev + 1;
+ }
+ else
+ {
+ prev = it;
+ }
+ }
+ }
+ ***/
+
+ // Check if some index combinations refer to larger combinations
+#if defined(BOOST_GEOMETRY_DEBUG_MARK_SPIKES)
+ for(typename boost::range_iterator<helper_vector_type>::type it
+ = boost::begin(candidates); it != boost::end(candidates); ++it)
+ {
+ std::cout << it->count << " " << it->index1 << " " << it->index2
+ << " gd=" << it->gap_distance
+ << " a=" << it->area << " p=" << it->perimeter
+ << " r=" << (it->perimeter > 0 ? it->area / it->perimeter : 0)
+ // << " p1=" << geometry::wkt(*it->it1) << " p2=" << geometry::wkt(*it->it2)
+ << std::endl;
+ }
+#endif
+
+ typedef typename MarkMap::mapped_type bit_vector_type;
+
+ // Add new vector to map if necessary
+ if (mark_map.find(id) == mark_map.end())
+ {
+ // Add one to vector
+ mark_map[id] = bit_vector_type();
+
+ // Initialize it
+ bit_vector_type& bits = mark_map[id];
+ for (std::size_t i = 0; i < n; i++)
+ {
+ bits.push_back(false);
+ }
+ }
+
+ bit_vector_type& bits = mark_map[id];
+
+ // Mark this range or these ranges
+ // TODO: we might use the fact that it is sorted and that ranges are inside others,
+ // so skip those...
+ for(typename boost::range_iterator<helper_vector_type const>::type it
+ = boost::begin(candidates); it != boost::end(candidates); ++it)
+ {
+ iterator_type pit = boost::begin(range) + it->index1;
+ iterator_type end = boost::begin(range) + it->index2;
+ int i = it->index1;
+ while (pit != end)
+ {
+ if (i != it->index1 && i != it->index2)
+ {
+ bits[i] = true;
+ }
+ pit = circular_next(range, pit);
+ i = circular_next_i(i, n);
+ }
+ }
+ }
+};
+
+
+template <typename Polygon, typename MarkMap, typename Policy>
+struct polygon_mark_spikes
+{
+ static inline void apply(Polygon const& polygon, ring_identifier id,
+ MarkMap& mark_map, Policy const& policy)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ typedef range_mark_spikes<ring_type, MarkMap, Policy> per_range;
+
+ // Exterior ring (-1)
+ id.ring_index = -1;
+ per_range::apply(exterior_ring(polygon), id, mark_map, policy);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ // Interior ring (zero based)
+ id.ring_index++;
+ per_range::apply(*it, id, mark_map, policy);
+ }
+ }
+};
+
+
+template <typename MultiGeometry, typename MarkMap, typename Policy, typename SinglePolicy>
+struct multi_mark_spikes
+{
+ static inline void apply(MultiGeometry const& multi, ring_identifier id,
+ MarkMap& mark_map, Policy const& policy)
+ {
+ id.multi_index = 0;
+ for (typename boost::range_iterator<MultiGeometry const>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ SinglePolicy::apply(*it, id, mark_map, policy);
+ id.multi_index++;
+ }
+ }
+};
+
+
+}} // namespace detail::mark_spikes
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename MarkMap,
+ typename Policy
+>
+struct mark_spikes
+{
+ static inline void apply(Geometry&, Policy const&)
+ {}
+};
+
+
+template <typename Ring, typename MarkMap, typename Policy>
+struct mark_spikes<ring_tag, Ring, MarkMap, Policy>
+ : detail::mark_spikes::range_mark_spikes<Ring, MarkMap, Policy>
+{};
+
+
+
+template <typename Polygon, typename MarkMap, typename Policy>
+struct mark_spikes<polygon_tag, Polygon, MarkMap, Policy>
+ : detail::mark_spikes::polygon_mark_spikes<Polygon, MarkMap, Policy>
+{};
+
+
+template <typename MultiPolygon, typename MarkMap, typename Policy>
+struct mark_spikes<multi_polygon_tag, MultiPolygon, MarkMap, Policy>
+ : detail::mark_spikes::multi_mark_spikes
+ <
+ MultiPolygon,
+ MarkMap,
+ Policy,
+ detail::mark_spikes::polygon_mark_spikes
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ MarkMap,
+ Policy
+ >
+ >
+{};
+
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+ \ingroup mark_spikes
+ \tparam Geometry geometry type
+ \param geometry the geometry to make mark_spikes
+*/
+template <typename Geometry, typename MarkMap, typename Policy>
+inline bool mark_spikes(Geometry const& geometry,
+ MarkMap& mark_map,
+ Policy const& policy)
+{
+ concept::check<Geometry const>();
+
+ ring_identifier id;
+
+ dispatch::mark_spikes
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ MarkMap,
+ Policy
+ >::apply(geometry, id, mark_map, policy);
+ return mark_map.size() > 0;
+}
+
+template <typename T = double>
+class select_gapped_spike
+{
+public :
+ inline select_gapped_spike(T const gap_width, T const ratio = 0.1)
+ : m_gap_width(gap_width)
+ , m_ratio(ratio)
+ {}
+
+
+ inline T gap_width() const
+ {
+ return m_gap_width;
+ }
+
+ inline bool apply(T const gap_distance, T const whole_area,
+ int count, T const area, T const perimeter) const
+ {
+ T const ratio = perimeter == 0 ? 0 : area / perimeter;
+ return
+ perimeter > gap_distance
+ && area < whole_area / 10.0
+ && ratio < m_ratio;
+ }
+
+
+private :
+ T m_gap_width;
+ T m_ratio;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_MARK_SPIKES_HPP
diff --git a/src/boost/geometry/extensions/algorithms/midpoints.hpp b/src/boost/geometry/extensions/algorithms/midpoints.hpp
new file mode 100644
index 0000000..6c669d7
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/midpoints.hpp
@@ -0,0 +1,131 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_MIDPOINTS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_MIDPOINTS_HPP
+
+// Renamed from "intermediate" to "midpoints"
+
+#include <cstddef>
+#include <iterator>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace midpoints {
+
+template <typename Src, typename Dst, std::size_t Dimension, std::size_t DimensionCount>
+struct calculate_coordinate
+{
+ static inline void apply(Src const& p1, Src const& p2, Dst& p)
+ {
+ geometry::set<Dimension>(p,
+ (geometry::get<Dimension>(p1) + geometry::get<Dimension>(p2)) / 2.0);
+ calculate_coordinate<Src, Dst, Dimension + 1, DimensionCount>::apply(p1, p2, p);
+ }
+};
+
+template <typename Src, typename Dst, std::size_t DimensionCount>
+struct calculate_coordinate<Src, Dst, DimensionCount, DimensionCount>
+{
+ static inline void apply(Src const&, Src const&, Dst&)
+ {
+ }
+};
+
+template<typename Range, typename Iterator>
+struct range_midpoints
+{
+ static inline void apply(Range const& range,
+ bool start_and_end, Iterator out)
+ {
+ typedef typename point_type<Range>::type point_type;
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ iterator_type it = boost::begin(range);
+
+ if (start_and_end)
+ {
+ *out++ = *it;
+ }
+
+ iterator_type prev = it++;
+ for (; it != boost::end(range); prev = it++)
+ {
+ point_type p;
+ calculate_coordinate
+ <
+ point_type,
+ point_type,
+ 0,
+ dimension<point_type>::type::value
+ >::apply(*prev, *it, p);
+ *out++ = p;
+ }
+
+ if (start_and_end)
+ {
+ *out++ = *prev;
+ }
+ }
+};
+
+}} // namespace detail::midpoints
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename G, typename Iterator>
+struct midpoints {};
+
+template <typename G, typename Iterator>
+struct midpoints<ring_tag, G, Iterator>
+ : detail::midpoints::range_midpoints<G, Iterator> {};
+
+template <typename G, typename Iterator>
+struct midpoints<linestring_tag, G, Iterator>
+ : detail::midpoints::range_midpoints<G, Iterator> {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Calculate midpoints of a geometry
+ \ingroup midpoints
+ */
+template<typename Geometry, typename Iterator>
+inline void midpoints(Geometry const& geometry,
+ bool start_and_end, Iterator out)
+{
+ concept::check<Geometry const>();
+
+ dispatch::midpoints
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Iterator
+ >::apply(geometry, start_and_end, out);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_MIDPOINTS_HPP
diff --git a/src/boost/geometry/extensions/algorithms/offset.hpp b/src/boost/geometry/extensions/algorithms/offset.hpp
new file mode 100644
index 0000000..bbbce8a
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/offset.hpp
@@ -0,0 +1,204 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_OFFSET_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_OFFSET_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/extensions/algorithms/buffer/line_line_intersection.hpp>
+#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/geometries/segment.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace offset
+{
+
+
+template
+<
+ typename Range,
+ typename RangeOut,
+ typename JoinStrategy,
+ typename Distance
+>
+struct offset_range
+{
+ typedef typename coordinate_type<RangeOut>::type coordinate_type;
+ typedef typename point_type<RangeOut>::type output_point_type;
+ typedef model::referring_segment<output_point_type const> segment_type;
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ static inline void apply(Range const& range,
+ RangeOut& out,
+ JoinStrategy const& join,
+ Distance const& distance)
+ {
+ output_point_type previous_p1, previous_p2;
+ output_point_type first_p1, first_p2;
+
+ bool first = true;
+
+ iterator_type it = boost::begin(range);
+ for (iterator_type prev = it++; it != boost::end(range); ++it)
+ {
+ if (! detail::equals::equals_point_point(*prev, *it))
+ {
+ bool skip = false;
+
+ // Simulate a vector d (dx,dy)
+ coordinate_type dx = get<0>(*it) - get<0>(*prev);
+ coordinate_type dy = get<1>(*it) - get<1>(*prev);
+
+ // For normalization [0,1] (=dot product d.d, sqrt)
+ coordinate_type length = sqrt(dx * dx + dy * dy);
+
+ // Because coordinates are not equal, length should not be zero
+ BOOST_ASSERT((! geometry::math::equals(length, 0)));
+
+ // Generate the normalized perpendicular p, to the left (ccw)
+ coordinate_type px = -dy / length;
+ coordinate_type py = dx / length;
+
+ output_point_type p1, p2;
+
+ set<0>(p2, get<0>(*it) + px * distance);
+ set<1>(p2, get<1>(*it) + py * distance);
+
+ set<0>(p1, get<0>(*prev) + px * distance);
+ set<1>(p1, get<1>(*prev) + py * distance);
+
+ if (! first)
+ {
+ output_point_type p;
+ segment_type s1(p1, p2);
+ segment_type s2(previous_p1, previous_p2);
+ if (detail::buffer::line_line_intersection<output_point_type, segment_type>::apply(s1, s2, p))
+ {
+ join.apply(p, *prev, previous_p2, p1, distance, out);
+ }
+ else
+ {
+ skip = false;
+ }
+ }
+ else
+ {
+ first = false;
+ first_p1 = p1;
+ first_p2 = p2;
+
+ out.push_back(p1);
+ }
+
+ if (! skip)
+ {
+ previous_p1 = p1;
+ previous_p2 = p2;
+ prev = it;
+ }
+ }
+ }
+
+ // Last one
+ out.push_back(previous_p2);
+
+ }
+};
+
+}} // namespace detail::offset
+#endif
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename GeometryTag,
+ typename GeometryOutTag,
+ typename Geometry,
+ typename GeometryOut,
+ typename JoinStrategy,
+ typename Distance
+>
+struct offset
+{};
+
+
+template
+<
+ typename Geometry,
+ typename GeometryOut,
+ typename JoinStrategy,
+ typename Distance
+>
+struct offset
+ <
+ linestring_tag,
+ linestring_tag,
+ Geometry,
+ GeometryOut,
+ JoinStrategy,
+ Distance
+ >
+ : detail::offset::offset_range
+ <
+ Geometry,
+ GeometryOut,
+ JoinStrategy,
+ Distance
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template
+<
+ typename Geometry,
+ typename GeometryOut,
+ typename JoinStrategy,
+ typename Distance
+>
+inline void offset(Geometry const& geometry, GeometryOut& out,
+ JoinStrategy const& join,
+ Distance const& distance)
+{
+ concept::check<Geometry const>();
+ concept::check<GeometryOut>();
+
+ dispatch::offset
+ <
+ typename tag<Geometry>::type,
+ typename tag<GeometryOut>::type,
+ Geometry,
+ GeometryOut,
+ JoinStrategy,
+ Distance
+ >::apply(geometry, out, join, distance);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_OFFSET_HPP
diff --git a/src/boost/geometry/extensions/algorithms/parse.hpp b/src/boost/geometry/extensions/algorithms/parse.hpp
new file mode 100644
index 0000000..db2d75c
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/parse.hpp
@@ -0,0 +1,123 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_PARSE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_PARSE_HPP
+
+#include <string>
+
+
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp>
+#include <boost/geometry/extensions/strategies/parse.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+template <typename Tag, typename G>
+struct parsing
+{
+};
+
+template <typename Point>
+struct parsing<point_tag, Point>
+{
+ template <typename S>
+ static inline void parse(Point& point, std::string const& c1, std::string const& c2, S const& strategy)
+ {
+ assert_dimension<Point, 2>();
+ dms_result r1 = strategy(c1.c_str());
+ dms_result r2 = strategy(c2.c_str());
+
+ if (0 == r1.axis())
+ set<0>(point, r1);
+ else
+ set<1>(point, r1);
+
+ if (0 == r2.axis())
+ set<0>(point, r2);
+ else
+ set<1>(point, r2);
+ }
+
+ static inline void parse(Point& point, std::string const& c1, std::string const& c2)
+ {
+ // strategy-parser corresponding to degree/radian
+ typename strategy_parse
+ <
+ typename cs_tag<Point>::type,
+ typename coordinate_system<Point>::type
+ >::type strategy;
+
+ parse(point, c1, c2, strategy);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief parse two strings to a spherical/geographic point, using W/E/N/S
+ \ingroup parse
+ */
+template <typename Geometry>
+inline void parse(Geometry& geometry, std::string const& c1, std::string const& c2)
+{
+ concept::check<Geometry>();
+ dispatch::parsing<typename tag<Geometry>::type, Geometry>::parse(geometry, c1, c2);
+}
+
+/*!
+ \brief parse two strings to a spherical/geographic point, using a specified strategy
+ \details user can use N/E/S/O or N/O/Z/W or other formats
+ \ingroup parse
+ */
+template <typename Geometry, typename S>
+inline void parse(Geometry& geometry, std::string const& c1,
+ std::string const& c2, S const& strategy)
+{
+ concept::check<Geometry>();
+ dispatch::parsing<typename tag<Geometry>::type, Geometry>::parse(geometry, c1, c2, strategy);
+}
+
+// There will be a parsing function with three arguments (ANGLE,ANGLE,RADIUS)
+
+template <typename Geometry>
+inline Geometry parse(std::string const& c1, std::string const& c2)
+{
+ concept::check<Geometry>();
+
+ Geometry geometry;
+ dispatch::parsing<typename tag<Geometry>::type, Geometry>::parse(geometry, c1, c2);
+ return geometry;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_PARSE_HPP
diff --git a/src/boost/geometry/extensions/algorithms/point_on_line.hpp b/src/boost/geometry/extensions/algorithms/point_on_line.hpp
new file mode 100644
index 0000000..77bb23f
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/point_on_line.hpp
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_POINT_ON_LINE_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_POINT_ON_LINE_HPP
+
+
+#include <boost/geometry/algorithms/distance.hpp>
+
+namespace boost { namespace geometry
+{
+
+//----------------------------------------------------------------------
+// Function : point_on_linestring -> rename to alongLine NO, different
+//----------------------------------------------------------------------
+// Purpose : Calculates coordinates of a point along a given line
+// on a specified distance
+// Parameters : const L& : line,
+// float position: position to calculate point
+// P& point: point to calculate
+// Return : true if point lies on line
+//----------------------------------------------------------------------
+// Author : Barend, Geodan BV Amsterdam
+// Date : spring 1996
+//----------------------------------------------------------------------
+template <typename P, typename L>
+bool point_on_linestring(L const& line, double const& position, P& point)
+{
+ double current_distance = 0.0;
+ if (line.size() < 2)
+ {
+ return false;
+ }
+
+ typename L::const_iterator vertex = line.begin();
+ typename L::const_iterator previous = vertex++;
+
+ while (vertex != line.end())
+ {
+ double const dist = distance(*previous, *vertex);
+ current_distance += dist;
+
+ if (current_distance > position)
+ {
+ // It is not possible that dist == 0 here because otherwise
+ // the current_distance > position would not become true (current_distance is increased by dist)
+ double const fraction = 1.0 - ((current_distance - position) / dist);
+
+ // point i is too far, point i-1 to near, add fraction of
+ // distance in each direction
+ point.x ( previous->x() + (vertex->x() - previous->x()) * fraction);
+ point.y ( previous->y() + (vertex->y() - previous->y()) * fraction);
+
+ return true;
+ }
+ previous = vertex++;
+ }
+
+ // point at specified position does not lie on line
+ return false;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_POINT_ON_LINE_HPP
diff --git a/src/boost/geometry/extensions/algorithms/remove_holes_if.hpp b/src/boost/geometry/extensions/algorithms/remove_holes_if.hpp
new file mode 100644
index 0000000..c187168
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/remove_holes_if.hpp
@@ -0,0 +1,166 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHM_REMOVE_HOLES_IF_HPP
+#define BOOST_GEOMETRY_ALGORITHM_REMOVE_HOLES_IF_HPP
+
+#include <algorithm>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/perimeter.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/multi/core/closure.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace remove_holes_if
+{
+
+
+template<typename Polygon, typename Predicate>
+struct polygon_remove_holes_if
+{
+ static inline void apply(Polygon& poly, Predicate const& predicate)
+ {
+ // TODO: evaluate this behaviour w.r.t. writable concepts
+ typename interior_return_type<Polygon>::type rings = interior_rings(poly);
+
+ // Remove rings using erase-remove-idiom
+ // http://en.wikipedia.org/wiki/Erase-remove_idiom
+ rings.erase(
+ std::remove_if(boost::begin(rings), boost::end(rings), predicate),
+ boost::end(rings));
+ }
+};
+
+}} // namespace detail::remove_holes_if
+
+
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// Default implementation does nothing
+template <typename Tag, typename Geometry, typename Predicate>
+struct remove_holes_if
+{};
+
+
+
+template <typename Geometry, typename Predicate>
+struct remove_holes_if<polygon_tag, Geometry, Predicate>
+ : detail::remove_holes_if::polygon_remove_holes_if<Geometry, Predicate>
+{};
+
+
+template <typename MultiPolygon, typename Predicate>
+struct remove_holes_if<multi_polygon_tag, MultiPolygon, Predicate>
+ : detail::multi_modify_with_predicate
+ <
+ MultiPolygon,
+ Predicate,
+ detail::remove_holes_if::polygon_remove_holes_if
+ <
+ typename boost::range_value<MultiPolygon>::type, Predicate
+ >
+ >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+ \brief Remove holes from a geometry (polygon, multi-polygon) using a specified condition
+ */
+template <typename Geometry, typename Predicate>
+inline void remove_holes_if(Geometry& geometry, Predicate const& predicate)
+{
+ concept::check<Geometry>();
+
+ dispatch::remove_holes_if
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Predicate
+ >::apply(geometry, predicate);
+}
+
+
+
+
+
+
+
+// CONVENIENT PREDICATES might be moved elsewhere
+template <typename Ring>
+struct elongated_hole
+{
+ inline elongated_hole(double ratio)
+ : m_ratio(ratio)
+ {}
+
+ inline bool operator()(Ring const& ring) const
+ {
+ if (ring.size() >=
+ core_detail::closure::minimum_ring_size
+ <
+ geometry::closure<Ring>::value
+ >::value)
+ {
+ double a = area(ring);
+ double p = perimeter(ring);
+ return geometry::math::abs(a / p) < m_ratio;
+ }
+ // Rings with less then 4 points (including closing)
+ // are also considered as small and thus removed
+ return true;
+ }
+private :
+ double m_ratio;
+};
+
+
+template <typename Ring>
+struct invalid_hole
+{
+ inline bool operator()(Ring const& ring) const
+ {
+ return ring.size()
+ < core_detail::closure::minimum_ring_size
+ <
+ geometry::closure<Ring>::value
+ >::value;
+ }
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ALGORITHM_REMOVE_HOLES_IF_HPP
diff --git a/src/boost/geometry/extensions/algorithms/remove_marked.hpp b/src/boost/geometry/extensions/algorithms/remove_marked.hpp
new file mode 100644
index 0000000..4f39b41
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/remove_marked.hpp
@@ -0,0 +1,224 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_REMOVE_MARKED_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_REMOVE_MARKED_HPP
+
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/perimeter.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace remove_marked
+{
+
+
+template <typename Range, typename MarkMap>
+struct range_remove_marked
+{
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Range>::type
+ >::type side_strategy_type;
+
+ typedef typename coordinate_type<Range>::type coordinate_type;
+
+
+ static inline void apply(Range const& range_in, ring_identifier id,
+ Range& range_out, MarkMap const& mark_map)
+ {
+ typename MarkMap::const_iterator mit = mark_map.find(id);
+ if (mit == mark_map.end())
+ {
+ range_out = range_in;
+ return;
+ }
+ typedef typename MarkMap::mapped_type bit_vector_type;
+
+ if (boost::size(range_in) != boost::size(mit->second))
+ {
+ throw std::runtime_error("ERROR in size of mark_map");
+ return;
+ }
+
+ range_out.clear();
+
+ typename boost::range_iterator<bit_vector_type const>::type bit = boost::begin(mit->second);
+ for (typename boost::range_iterator<Range const>::type it = boost::begin(range_in);
+ it != boost::end(range_in); ++it, ++bit)
+ {
+ bool const& marked = *bit;
+ if (! marked)
+ {
+ range_out.push_back(*it);
+ }
+ }
+ }
+};
+
+
+template <typename Polygon, typename MarkMap>
+struct polygon_remove_marked
+{
+ static inline void apply(Polygon const& polygon_in, ring_identifier id,
+ Polygon& polygon_out, MarkMap const& mark_map)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ typedef range_remove_marked<ring_type, MarkMap> per_range;
+ id.ring_index = -1;
+ per_range::apply(exterior_ring(polygon_in), id, exterior_ring(polygon_out), mark_map);
+
+
+ typename interior_return_type<Polygon const>::type rings_in
+ = interior_rings(polygon_in);
+ typename interior_return_type<Polygon>::type rings_out
+ = interior_rings(polygon_out);
+
+ rings_out.resize(boost::size(interior_rings(polygon_in)));
+ BOOST_AUTO_TPL(out, boost::begin(rings_out));
+
+ for (BOOST_AUTO_TPL(it, boost::begin(rings_in));
+ it != boost::end(rings_in);
+ ++it, ++out)
+ {
+ id.ring_index++;
+ per_range::apply(*it, id, *out, mark_map);
+ }
+ }
+};
+
+
+template <typename MultiGeometry, typename MarkMap, typename SinglePolicy>
+struct multi_remove_marked
+{
+ static inline void apply(MultiGeometry const& multi_in, ring_identifier id,
+ MultiGeometry& multi_out, MarkMap const& mark_map)
+ {
+ id.multi_index = 0;
+
+ multi_out.resize(boost::size(multi_in));
+
+ typename boost::range_iterator<MultiGeometry>::type out = boost::begin(multi_out);
+ for (typename boost::range_iterator<MultiGeometry const>::type
+ it = boost::begin(multi_in);
+ it != boost::end(multi_in);
+ ++it, ++out)
+ {
+ SinglePolicy::apply(*it, id, *out, mark_map);
+ id.multi_index++;
+ }
+ }
+};
+
+
+}} // namespace detail::remove_marked
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename MarkMap
+>
+struct remove_marked
+{
+ static inline void apply(Geometry const&, ring_identifier, Geometry&, MarkMap const&)
+ {}
+};
+
+
+template <typename Ring, typename MarkMap>
+struct remove_marked<ring_tag, Ring, MarkMap>
+ : detail::remove_marked::range_remove_marked<Ring, MarkMap>
+{};
+
+
+
+template <typename Polygon, typename MarkMap>
+struct remove_marked<polygon_tag, Polygon, MarkMap>
+ : detail::remove_marked::polygon_remove_marked<Polygon, MarkMap>
+{};
+
+
+template <typename MultiPolygon, typename MarkMap>
+struct remove_marked<multi_polygon_tag, MultiPolygon, MarkMap>
+ : detail::remove_marked::multi_remove_marked
+ <
+ MultiPolygon,
+ MarkMap,
+ detail::remove_marked::polygon_remove_marked
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ MarkMap
+ >
+ >
+{};
+
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+ \ingroup remove_marked
+ \tparam Geometry geometry type
+ \param geometry the geometry to make remove_marked
+*/
+template <typename Geometry, typename MarkMap>
+inline void remove_marked(Geometry const& geometry_in, Geometry& geometry_out,
+ MarkMap const& mark_map)
+{
+ concept::check<Geometry>();
+
+ ring_identifier id;
+ dispatch::remove_marked
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ MarkMap
+ >::apply(geometry_in, id, geometry_out, mark_map);
+}
+
+
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_REMOVE_MARKED_HPP
diff --git a/src/boost/geometry/extensions/algorithms/remove_spikes.hpp b/src/boost/geometry/extensions/algorithms/remove_spikes.hpp
new file mode 100644
index 0000000..aea900d
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/remove_spikes.hpp
@@ -0,0 +1,378 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_REMOVE_SPIKES_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_REMOVE_SPIKES_HPP
+
+// NOTE: obsolete by "mark_spikes"
+
+#include <algorithm>
+#include <deque>
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/perimeter.hpp>
+
+#include <boost/geometry/iterators/ever_circling_iterator.hpp>
+
+#include <boost/geometry/geometries/ring.hpp>
+
+
+/*
+Remove spikes from a ring/polygon.
+Ring (having 8 vertices, including closing vertex)
++------+
+| |
+| +--+
+| | ^this "spike" is removed, can be located outside/inside the ring
++------+
+(the actualy determination if it is removed is done by a strategy)
+
+*/
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace remove_spikes
+{
+
+
+template <typename Range, typename Policy>
+struct range_remove_spikes
+{
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Range>::type
+ >::type side_strategy_type;
+
+ typedef typename coordinate_type<Range>::type coordinate_type;
+
+
+ static inline void apply(Range& range, Policy const& policy)
+ {
+ std::size_t n = boost::size(range);
+ if (n < 3)
+ {
+ return;
+ }
+
+ typedef typename boost::range_iterator<Range>::type iterator;
+ ever_circling_iterator<iterator> it(boost::begin(range), boost::end(range), true);
+ ever_circling_iterator<iterator> next(boost::begin(range), boost::end(range), true);
+ ever_circling_iterator<iterator> prev(boost::begin(range), boost::end(range), true);
+ // If it is "closed", skip the last (or actually the first coming after last) one.
+ n--;
+
+ it++;
+ next++;
+ next++;
+
+ bool close = false;
+
+ std::deque<std::size_t> vertices;
+ for (std::size_t i = 0;
+ i < n;
+ ++i, ++it, ++next)
+ {
+ if (policy(*prev, *it, *next))
+ {
+ // It is collinear, middle point (i == 1) will be removed below
+ vertices.push_back(i + 1);
+ if (i == n - 1)
+ {
+ vertices.push_front(0);
+ close = true;
+ }
+ }
+ else
+ {
+ prev = it;
+ }
+ }
+ for (std::deque<std::size_t>::reverse_iterator rit = vertices.rbegin();
+ rit != vertices.rend(); ++rit)
+ {
+ range.erase(range.begin() + *rit);
+ }
+ if (close)
+ {
+ typename point_type<Range>::type p = range.front();
+ range.push_back(p);
+ }
+ }
+};
+
+
+template <typename Polygon, typename Policy>
+struct polygon_remove_spikes
+{
+ static inline void apply(Polygon& polygon, Policy const& policy)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ typedef range_remove_spikes<ring_type, Policy> per_range;
+ per_range::apply(exterior_ring(polygon), policy);
+
+ typename interior_return_type<Polygon>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ per_range::apply(*it, policy);
+ }
+ }
+};
+
+
+template <typename MultiGeometry, typename Policy, typename SinglePolicy>
+struct multi_remove_spikes
+{
+ static inline void apply(MultiGeometry& multi, Policy const& policy)
+ {
+ for (typename boost::range_iterator<MultiGeometry>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ SinglePolicy::apply(*it, policy);
+ }
+ }
+};
+
+
+}} // namespace detail::remove_spikes
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Tag,
+ typename Geometry,
+ typename Policy
+>
+struct remove_spikes
+{
+ static inline void apply(Geometry&, Policy const&)
+ {}
+};
+
+
+template <typename Ring, typename Policy>
+struct remove_spikes<ring_tag, Ring, Policy>
+ : detail::remove_spikes::range_remove_spikes<Ring, Policy>
+{};
+
+
+
+template <typename Polygon, typename Policy>
+struct remove_spikes<polygon_tag, Polygon, Policy>
+ : detail::remove_spikes::polygon_remove_spikes<Polygon, Policy>
+{};
+
+
+template <typename MultiPolygon, typename Policy>
+struct remove_spikes<multi_polygon_tag, MultiPolygon, Policy>
+ : detail::remove_spikes::multi_remove_spikes
+ <
+ MultiPolygon,
+ Policy,
+ detail::remove_spikes::polygon_remove_spikes
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ Policy
+ >
+ >
+{};
+
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+ \ingroup remove_spikes
+ \tparam Geometry geometry type
+ \param geometry the geometry to make remove_spikes
+*/
+template <typename Geometry, typename Policy>
+inline void remove_spikes(Geometry& geometry, Policy const& policy)
+{
+ concept::check<Geometry>();
+
+ dispatch::remove_spikes
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Policy
+ >::apply(geometry, policy);
+}
+
+
+
+template <typename Point>
+struct remove_elongated_spikes
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+ coordinate_type m_area_div_peri;
+ coordinate_type m_dist_div_peri;
+ coordinate_type m_area_limit;
+ coordinate_type m_distance_limit;
+ coordinate_type m_zero;
+
+
+ inline remove_elongated_spikes(coordinate_type const& area_div_peri = 0.001
+ , coordinate_type const& dist_div_peri = 0.001
+ , coordinate_type const& area_limit = 0.01
+ , coordinate_type const& distance_limit = 1
+ )
+ : m_area_div_peri(area_div_peri)
+ , m_dist_div_peri(dist_div_peri)
+ , m_area_limit(area_limit)
+ , m_distance_limit(distance_limit)
+ , m_zero(coordinate_type())
+ {}
+
+
+ inline bool operator()(Point const& prev,
+ Point const& current, Point const& next) const
+ {
+ coordinate_type d1 = geometry::distance(prev, current);
+ if (d1 < m_distance_limit)
+ {
+ geometry::model::ring<Point> triangle;
+ triangle.push_back(prev);
+ triangle.push_back(current);
+ triangle.push_back(next);
+ triangle.push_back(prev);
+
+ coordinate_type p = geometry::perimeter(triangle);
+ if (p > m_zero)
+ {
+ coordinate_type a = abs(geometry::area(triangle));
+ coordinate_type prop1 = a / p;
+ coordinate_type prop2 = d1 / p;
+
+ bool remove = prop1 < m_area_div_peri
+ && prop2 < m_dist_div_peri
+ && a < m_area_limit;
+
+ /*
+ {
+ coordinate_type d2 = geometry::distance(prev, next);
+ std::cout << std::endl;
+ std::cout << "Distance1: " << d1 << std::endl;
+ std::cout << "Distance2: " << d2 << std::endl;
+ std::cout << "Area: " << a << std::endl;
+ std::cout << "Perimeter: " << p << std::endl;
+ std::cout << "Prop1: " << prop1 << std::endl;
+ std::cout << "Prop2: " << prop2 << std::endl;
+ std::cout << "Remove: " << (remove ? "true" : "false") << std::endl;
+ }
+ */
+
+ return remove;
+ }
+ }
+ return false;
+ }
+};
+
+
+template <typename Point>
+class remove_by_normalized
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+ coordinate_type m_zero;
+ coordinate_type m_limit;
+
+public :
+ inline remove_by_normalized(coordinate_type const& lm = 1.0e-7)
+ : m_zero(coordinate_type())
+ , m_limit(lm)
+ {}
+
+ inline bool operator()(Point const& prev,
+ Point const& current, Point const& next) const
+ {
+ coordinate_type const x1 = get<0>(prev);
+ coordinate_type const y1 = get<1>(prev);
+ coordinate_type const x2 = get<0>(current);
+ coordinate_type const y2 = get<1>(current);
+
+ coordinate_type dx1 = x2 - x1;
+ coordinate_type dy1 = y2 - y1;
+
+ // Duplicate points (can be created by removing spikes)
+ // can be removed as well. (Can be seen as a spike without length)
+ if (geometry::math::equals(dx1, 0) && geometry::math::equals(dy1, 0))
+ {
+ return true;
+ }
+
+ coordinate_type dx2 = get<0>(next) - x2;
+ coordinate_type dy2 = get<1>(next) - y2;
+
+ // If middle point is duplicate with next, also.
+ if (geometry::math::equals(dx2, 0) && geometry::math::equals(dy2, 0))
+ {
+ return true;
+ }
+
+ // Normalize the vectors -> this results in points+direction
+ // and is comparible between geometries
+ coordinate_type const magnitude1 = sqrt(dx1 * dx1 + dy1 * dy1);
+ coordinate_type const magnitude2 = sqrt(dx2 * dx2 + dy2 * dy2);
+
+ if (magnitude1 > m_zero && magnitude2 > m_zero)
+ {
+ dx1 /= magnitude1;
+ dy1 /= magnitude1;
+ dx2 /= magnitude2;
+ dy2 /= magnitude2;
+
+ // If the directions are opposite, it can be removed
+ if (geometry::math::abs(dx1 + dx2) < m_limit
+ && geometry::math::abs(dy1 + dy2) < m_limit)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_REMOVE_SPIKES_HPP
diff --git a/src/boost/geometry/extensions/algorithms/selected.hpp b/src/boost/geometry/extensions/algorithms/selected.hpp
new file mode 100644
index 0000000..0b1a1e3
--- /dev/null
+++ b/src/boost/geometry/extensions/algorithms/selected.hpp
@@ -0,0 +1,278 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_SELECTED_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_SELECTED_HPP
+
+#include <cmath>
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <boost/geometry/algorithms/within.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/topological_dimension.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+ \ingroup impl
+ */
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace selected
+{
+
+/*!
+\details Checks, per dimension, if d[I] not larger than search distance. If true for all
+dimensions then returns true. If larger stops immediately and returns false.
+Calculate during this process the sum, which is only valid if returning true
+*/
+template <typename P1, typename P2, typename T, std::size_t D, std::size_t N>
+struct differences_loop
+{
+ static inline bool apply(P1 const& p1, P2 const& p2, T const& distance, T& sum)
+ {
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+ coordinate_type const c1 = boost::numeric_cast<coordinate_type>(get<D>(p1));
+ coordinate_type const c2 = boost::numeric_cast<coordinate_type>(get<D>(p2));
+
+ T const d = geometry::math::abs(c1 - c2);
+ if (d > distance)
+ {
+ return false;
+ }
+ sum += d * d;
+ return differences_loop<P1, P2, T, D + 1, N>::apply(p1, p2, distance, sum);
+ }
+};
+
+template <typename P1, typename P2, typename T, std::size_t N>
+struct differences_loop<P1, P2, T, N, N>
+{
+ static inline bool apply(P1 const&, P2 const&, T const&, T&)
+ {
+ return true;
+ }
+};
+
+
+
+template <typename PS, typename P, typename T, std::size_t D, std::size_t N>
+struct outside_loop
+{
+ static inline bool apply(PS const& seg1, PS const& seg2, P const& point, T const& distance)
+ {
+ typedef typename select_coordinate_type<PS, P>::type coordinate_type;
+
+ coordinate_type const v = boost::numeric_cast<coordinate_type>(get<D>(point));
+ coordinate_type const s1 = get<D>(seg1);
+ coordinate_type const s2 = get<D>(seg2);
+
+ // Out of reach if left/bottom or right/top of both points making up the segment
+ // I know and currently accept that these comparisons/calculations are done twice per point
+
+ if ((v < s1 - distance && v < s2 - distance) || (v > s1 + distance && v > s2 + distance))
+ {
+ return true;
+ }
+ return outside_loop<PS, P, T, D + 1, N>::apply(seg1, seg2, point, distance);
+ }
+};
+
+template <typename PS, typename P, typename T, std::size_t N>
+struct outside_loop<PS, P, T, N, N>
+{
+ static inline bool apply(PS const&, PS const&, P const&, T const&)
+ {
+ return false;
+ }
+};
+
+
+template <typename P1, typename P2, typename T>
+struct close_to_point
+{
+ static inline bool apply(P1 const& point, P1 const& selection_point, T const& search_radius)
+ {
+ assert_dimension_equal<P1, P2>();
+
+ T sum = 0;
+ if (differences_loop
+ <
+ P1, P2, T, 0, dimension<P1>::type::value
+ >::apply(point, selection_point, search_radius, sum))
+ {
+ return sum <= search_radius * search_radius;
+ }
+
+ return false;
+ }
+};
+
+template <typename PS, typename P, typename T>
+struct close_to_segment
+{
+ static inline bool apply(PS const& seg1, PS const& seg2, P const& selection_point, T const& search_radius)
+ {
+ assert_dimension_equal<PS, P>();
+
+ if (! outside_loop
+ <
+ PS, P, T, 0, dimension<P>::type::value
+ >::apply(seg1, seg2, selection_point, search_radius))
+ {
+ // Not outside, calculate dot product/square distance to segment.
+ // Call corresponding strategy
+ typedef typename strategy::distance::services::default_strategy
+ <
+ segment_tag, P, PS
+ >::type strategy_type;
+ typedef typename strategy::distance::services::return_type<strategy_type>::type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(selection_point, seg1, seg2);
+ return result < search_radius;
+ }
+
+ return false;
+ }
+};
+
+template <typename R, typename P, typename T>
+struct close_to_range
+{
+ static inline bool apply(R const& range, P const& selection_point, T const& search_radius)
+ {
+ assert_dimension_equal<R, P>();
+
+ std::size_t const n = boost::size(range);
+ if (n == 0)
+ {
+ // Line with zero points, never close
+ return false;
+ }
+
+ typedef typename point_type<R>::type point_type;
+ typedef typename boost::range_iterator<R const>::type iterator_type;
+
+ iterator_type it = boost::begin(range);
+ if (n == 1)
+ {
+ // Line with one point ==> close to point
+ return close_to_point<P, point_type, T>::apply(*it, selection_point, search_radius);
+ }
+
+ iterator_type previous = it++;
+ while(it != boost::end(range))
+ {
+ //typedef segment<point_type const> segment_type;
+ //segment_type s(*previous, *it);
+ if (close_to_segment
+ <
+ point_type, P, T
+ >::apply(*previous, *it, selection_point, search_radius))
+ {
+ return true;
+ }
+ previous = it++;
+ }
+
+ return false;
+ }
+};
+
+template <typename Tag, typename G, typename P, typename T>
+struct use_within
+{
+ static inline bool apply(G const& geometry, P const& selection_point, T const& search_radius)
+ {
+ return geometry::within(selection_point, geometry);
+ }
+};
+
+}} // namespace detail::selected
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+/*!
+ \tparam TD topological dimension
+ */
+template <typename Tag, typename G, std::size_t D, typename P, typename T>
+struct selected
+{
+};
+
+template <typename P1, typename P2, typename T>
+struct selected<point_tag, P1, 0, P2, T> : detail::selected::close_to_point<P1, P2, T> { };
+
+// SEGMENT, TODO HERE (close_to_segment)
+
+template <typename L, typename P, typename T>
+struct selected<linestring_tag, L, 1, P, T> : detail::selected::close_to_range<L, P, T> { };
+
+template <typename Tag, typename G, typename P, typename T>
+struct selected<Tag, G, 2, P, T> : detail::selected::use_within<Tag, G, P, T> { };
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+ \brief Checks if one geometry is selected by a point lying within or in the neighborhood of that geometry
+ \ingroup selected
+ \tparam Geometry type of geometry to check
+ \tparam Point type of point to check
+ \tparam T type of search radius
+ \param geometry geometry which might be located in the neighborhood
+ \param selection_point point to select the geometry
+ \param search_radius for points/linestrings: defines radius of "neighborhood" to find things in
+ \return true if point is within or close to the other geometry
+
+ */
+template<typename Geometry, typename Point, typename RadiusType>
+inline bool selected(Geometry const& geometry,
+ Point const& selection_point,
+ RadiusType const& search_radius)
+{
+ concept::check<Geometry const>();
+ concept::check<Point const>();
+
+ typedef dispatch::selected
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ topological_dimension<Geometry>::value,
+ Point,
+ RadiusType
+ > selector_type;
+
+ return selector_type::apply(geometry, selection_point, search_radius);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_SELECTED_HPP
diff --git a/src/boost/geometry/extensions/arithmetic/cross_product.hpp b/src/boost/geometry/extensions/arithmetic/cross_product.hpp
new file mode 100644
index 0000000..fcf4ec2
--- /dev/null
+++ b/src/boost/geometry/extensions/arithmetic/cross_product.hpp
@@ -0,0 +1,109 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ARITHMETIC_CROSS_PRODUCT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ARITHMETIC_CROSS_PRODUCT_HPP
+
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P1, typename P2, std::size_t Dimension>
+struct cross_product
+{
+ // We define cross product only for 2d (see Wolfram) and 3d.
+ // In Math, it is also well-defined for 7-dimension.
+ // Generalisation of cross product to n-dimension is defined as
+ // wedge product but it is not direct analogue to binary cross product.
+};
+
+template <typename P1, typename P2>
+struct cross_product<P1, P2, 2>
+{
+ typedef P1 return_type;
+
+ static inline return_type apply(P1 const& p1, P2 const& p2)
+ {
+ assert_dimension<P1, 2>();
+ assert_dimension<P2, 2>();
+
+ // For 2-dimensions, analog of the cross product U(x,y) and V(x,y) is
+ // Ux * Vy - Uy * Vx
+ // which is returned as 0-component (or X) of 2d vector, 1-component is undefined.
+ return_type v;
+ set<0>(v, get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
+ return v;
+ }
+};
+
+template <typename P1, typename P2>
+struct cross_product<P1, P2, 3>
+{
+ typedef P1 return_type;
+
+ static inline return_type apply(P1 const& p1, P2 const& p2)
+ {
+ assert_dimension<P1, 3>();
+ assert_dimension<P2, 3>();
+
+ return_type v;
+ set<0>(v, get<1>(p1) * get<2>(p2) - get<2>(p1) * get<1>(p2));
+ set<1>(v, get<2>(p1) * get<0>(p2) - get<0>(p1) * get<2>(p2));
+ set<2>(v, get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
+ return v;
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+// TODO: This is a simple draft. If relevant, it can be extended to:
+// - accept vectors of different coordinate_type, but common coordinate_system
+// - if vectors are of mixed 2d and 3d, lower dimension is used
+// - define result_type that will generate type of vector based on:
+// -- select_coordinate_type
+// -- selection of lower dimension
+
+/*!
+ \brief Computes the cross product of two vector.
+ \details Both vectors shall be of the same type.
+ This type also determines type of result vector.
+ \ingroup arithmetic
+ \param p1 first vector
+ \param p2 second vector
+ \return the cross product vector
+ */
+template <typename P1, typename P2>
+inline P1 cross_product(P1 const& p1, P2 const& p2)
+{
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P1>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P2>) );
+
+ return detail::cross_product
+ <
+ P1, P2,
+ dimension<P1>::type::value
+ >::apply(p1, p2);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ARITHMETIC_CROSS_PRODUCT_HPP
diff --git a/src/boost/geometry/extensions/astronomy/core/cs.hpp b/src/boost/geometry/extensions/astronomy/core/cs.hpp
new file mode 100644
index 0000000..c5833a3
--- /dev/null
+++ b/src/boost/geometry/extensions/astronomy/core/cs.hpp
@@ -0,0 +1,53 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSION_ASTRONOMY_CORE_CS_HPP
+#define BOOST_GEOMETRY_EXTENSION_ASTRONOMY_CORE_CS_HPP
+
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace cs
+{
+
+
+namespace celestial
+{
+
+/*!
+ \brief Ecliptic (celestial) coordinate system
+ \details Defines the astronomical ecliptic coordinate system "that uses the ecliptic for its fundamental plane"
+ It uses Beta and Lambda as its latitude and longitude.
+ \see http://en.wikipedia.org/wiki/Ecliptic_coordinate_system
+ \ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct ecliptic
+{
+ typedef DegreeOrRadian units;
+};
+
+
+} // namespace celestial
+
+} // namespace cs
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSION_ASTRONOMY_CORE_CS_HPP
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmath.h b/src/boost/geometry/extensions/contrib/ttmath/ttmath.h
new file mode 100644
index 0000000..37c971f
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmath.h
@@ -0,0 +1,2849 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathmathtt
+#define headerfilettmathmathtt
+
+/*!
+ \file ttmath.h
+ \brief Mathematics functions.
+*/
+
+#ifdef _MSC_VER
+//warning C4127: conditional expression is constant
+#pragma warning( disable: 4127 )
+//warning C4702: unreachable code
+#pragma warning( disable: 4702 )
+//warning C4800: forcing value to bool 'true' or 'false' (performance warning)
+#pragma warning( disable: 4800 )
+#endif
+
+
+#include "ttmathbig.h"
+#include "ttmathobjects.h"
+
+
+namespace ttmath
+{
+ /*
+ *
+ * functions defined here are used only with Big<> types
+ *
+ *
+ */
+
+
+ /*
+ *
+ * functions for rounding
+ *
+ *
+ */
+
+
+ /*!
+ this function skips the fraction from x
+ e.g 2.2 = 2
+ 2.7 = 2
+ -2.2 = 2
+ -2.7 = 2
+ */
+ template<class ValueType>
+ ValueType SkipFraction(const ValueType & x)
+ {
+ ValueType result( x );
+ result.SkipFraction();
+
+ return result;
+ }
+
+
+ /*!
+ this function rounds to the nearest integer value
+ e.g 2.2 = 2
+ 2.7 = 3
+ -2.2 = -2
+ -2.7 = -3
+ */
+ template<class ValueType>
+ ValueType Round(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType result( x );
+ uint c = result.Round();
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+
+ /*!
+ this function returns a value representing the smallest integer
+ that is greater than or equal to x
+
+ Ceil(-3.7) = -3
+ Ceil(-3.1) = -3
+ Ceil(-3.0) = -3
+ Ceil(4.0) = 4
+ Ceil(4.2) = 5
+ Ceil(4.8) = 5
+ */
+ template<class ValueType>
+ ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType result(x);
+ uint c = 0;
+
+ result.SkipFraction();
+
+ if( result != x )
+ {
+ // x is with fraction
+ // if x is negative we don't have to do anything
+ if( !x.IsSign() )
+ {
+ ValueType one;
+ one.SetOne();
+
+ c += result.Add(one);
+ }
+ }
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ this function returns a value representing the largest integer
+ that is less than or equal to x
+
+ Floor(-3.6) = -4
+ Floor(-3.1) = -4
+ Floor(-3) = -3
+ Floor(2) = 2
+ Floor(2.3) = 2
+ Floor(2.8) = 2
+ */
+ template<class ValueType>
+ ValueType Floor(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType result(x);
+ uint c = 0;
+
+ result.SkipFraction();
+
+ if( result != x )
+ {
+ // x is with fraction
+ // if x is positive we don't have to do anything
+ if( x.IsSign() )
+ {
+ ValueType one;
+ one.SetOne();
+
+ c += result.Sub(one);
+ }
+ }
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+
+ /*
+ *
+ * logarithms and the exponent
+ *
+ *
+ */
+
+
+ /*!
+ this function calculates the natural logarithm (logarithm with the base 'e')
+ */
+ template<class ValueType>
+ ValueType Ln(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType result;
+ uint state = result.Ln(x);
+
+ if( err )
+ {
+ switch( state )
+ {
+ case 0:
+ *err = err_ok;
+ break;
+ case 1:
+ *err = err_overflow;
+ break;
+ case 2:
+ *err = err_improper_argument;
+ break;
+ default:
+ *err = err_internal_error;
+ break;
+ }
+ }
+
+
+ return result;
+ }
+
+
+ /*!
+ this function calculates the logarithm
+ */
+ template<class ValueType>
+ ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err ) *err = err_improper_argument;
+ return x;
+ }
+
+ if( base.IsNan() )
+ {
+ if( err ) *err = err_improper_argument;
+ return base;
+ }
+
+ ValueType result;
+ uint state = result.Log(x, base);
+
+ if( err )
+ {
+ switch( state )
+ {
+ case 0:
+ *err = err_ok;
+ break;
+ case 1:
+ *err = err_overflow;
+ break;
+ case 2:
+ case 3:
+ *err = err_improper_argument;
+ break;
+ default:
+ *err = err_internal_error;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+
+ /*!
+ this function calculates the expression e^x
+ */
+ template<class ValueType>
+ ValueType Exp(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType result;
+ uint c = result.Exp(x);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ *
+ * trigonometric functions
+ *
+ */
+
+
+ /*
+ this namespace consists of auxiliary functions
+ (something like 'private' in a class)
+ */
+ namespace auxiliaryfunctions
+ {
+
+ /*!
+ an auxiliary function for calculating the Sine
+ (you don't have to call this function)
+ */
+ template<class ValueType>
+ uint PrepareSin(ValueType & x, bool & change_sign)
+ {
+ ValueType temp;
+
+ change_sign = false;
+
+ if( x.IsSign() )
+ {
+ // we're using the formula 'sin(-x) = -sin(x)'
+ change_sign = !change_sign;
+ x.ChangeSign();
+ }
+
+ // we're reducing the period 2*PI
+ // (for big values there'll always be zero)
+ temp.Set2Pi();
+
+ if( x.Mod(temp) )
+ return 1;
+
+
+ // we're setting 'x' as being in the range of <0, 0.5PI>
+
+ temp.SetPi();
+
+ if( x > temp )
+ {
+ // x is in (pi, 2*pi>
+ x.Sub( temp );
+ change_sign = !change_sign;
+ }
+
+ temp.Set05Pi();
+
+ if( x > temp )
+ {
+ // x is in (0.5pi, pi>
+ x.Sub( temp );
+ x = temp - x;
+ }
+
+ return 0;
+ }
+
+
+ /*!
+ an auxiliary function for calculating the Sine
+ (you don't have to call this function)
+
+ it returns Sin(x) where 'x' is from <0, PI/2>
+ we're calculating the Sin with using Taylor series in zero or PI/2
+ (depending on which point of these two points is nearer to the 'x')
+
+ Taylor series:
+ sin(x) = sin(a) + cos(a)*(x-a)/(1!)
+ - sin(a)*((x-a)^2)/(2!) - cos(a)*((x-a)^3)/(3!)
+ + sin(a)*((x-a)^4)/(4!) + ...
+
+ when a=0 it'll be:
+ sin(x) = (x)/(1!) - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) + (x^9)/(9!) ...
+
+ and when a=PI/2:
+ sin(x) = 1 - ((x-PI/2)^2)/(2!) + ((x-PI/2)^4)/(4!) - ((x-PI/2)^6)/(6!) ...
+ */
+ template<class ValueType>
+ ValueType Sin0pi05(const ValueType & x)
+ {
+ ValueType result;
+ ValueType numerator, denominator;
+ ValueType d_numerator, d_denominator;
+ ValueType one, temp, old_result;
+
+ // temp = pi/4
+ temp.Set05Pi();
+ temp.exponent.SubOne();
+
+ one.SetOne();
+
+ if( x < temp )
+ {
+ // we're using the Taylor series with a=0
+ result = x;
+ numerator = x;
+ denominator = one;
+
+ // d_numerator = x^2
+ d_numerator = x;
+ d_numerator.Mul(x);
+
+ d_denominator = 2;
+ }
+ else
+ {
+ // we're using the Taylor series with a=PI/2
+ result = one;
+ numerator = one;
+ denominator = one;
+
+ // d_numerator = (x-pi/2)^2
+ ValueType pi05;
+ pi05.Set05Pi();
+
+ temp = x;
+ temp.Sub( pi05 );
+ d_numerator = temp;
+ d_numerator.Mul( temp );
+
+ d_denominator = one;
+ }
+
+ uint c = 0;
+ bool addition = false;
+
+ old_result = result;
+ for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+ {
+ // we're starting from a second part of the formula
+ c += numerator. Mul( d_numerator );
+ c += denominator. Mul( d_denominator );
+ c += d_denominator.Add( one );
+ c += denominator. Mul( d_denominator );
+ c += d_denominator.Add( one );
+ temp = numerator;
+ c += temp.Div(denominator);
+
+ if( c )
+ // Sin is from <-1,1> and cannot make an overflow
+ // but the carry can be from the Taylor series
+ // (then we only break our calculations)
+ break;
+
+ if( addition )
+ result.Add( temp );
+ else
+ result.Sub( temp );
+
+
+ addition = !addition;
+
+ // we're testing whether the result has changed after adding
+ // the next part of the Taylor formula, if not we end the loop
+ // (it means 'x' is zero or 'x' is PI/2 or this part of the formula
+ // is too small)
+ if( result == old_result )
+ break;
+
+ old_result = result;
+ }
+
+ return result;
+ }
+
+ } // namespace auxiliaryfunctions
+
+
+
+ /*!
+ this function calculates the Sine
+ */
+ template<class ValueType>
+ ValueType Sin(ValueType x, ErrorCode * err = 0)
+ {
+ using namespace auxiliaryfunctions;
+
+ ValueType one, result;
+ bool change_sign;
+
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x;
+ }
+
+ if( err )
+ *err = err_ok;
+
+ if( PrepareSin( x, change_sign ) )
+ {
+ // x is too big, we cannnot reduce the 2*PI period
+ // prior to version 0.8.5 the result was zero
+
+ // result has NaN flag set by default
+
+ if( err )
+ *err = err_overflow; // maybe another error code? err_improper_argument?
+
+ return result; // NaN is set by default
+ }
+
+ result = Sin0pi05( x );
+
+ one.SetOne();
+
+ // after calculations there can be small distortions in the result
+ if( result > one )
+ result = one;
+ else
+ if( result.IsSign() )
+ // we've calculated the sin from <0, pi/2> and the result
+ // should be positive
+ result.SetZero();
+
+ if( change_sign )
+ result.ChangeSign();
+
+ return result;
+ }
+
+
+ /*!
+ this function calulates the Cosine
+ we're using the formula cos(x) = sin(x + PI/2)
+ */
+ template<class ValueType>
+ ValueType Cos(ValueType x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType pi05;
+ pi05.Set05Pi();
+
+ uint c = x.Add( pi05 );
+
+ if( c )
+ {
+ if( err )
+ *err = err_overflow;
+
+ return ValueType(); // result is undefined (NaN is set by default)
+ }
+
+ return Sin(x, err);
+ }
+
+
+ /*!
+ this function calulates the Tangent
+ we're using the formula tan(x) = sin(x) / cos(x)
+
+ it takes more time than calculating the Tan directly
+ from for example Taylor series but should be a bit preciser
+ because Tan receives its values from -infinity to +infinity
+ and when we calculate it from any series then we can make
+ a greater mistake than calculating 'sin/cos'
+ */
+ template<class ValueType>
+ ValueType Tan(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType result = Cos(x, err);
+
+ if( err && *err != err_ok )
+ return result;
+
+ if( result.IsZero() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ result.SetNan();
+
+ return result;
+ }
+
+ return Sin(x, err) / result;
+ }
+
+
+ /*!
+ this function calulates the Tangent
+ look at the description of Tan(...)
+
+ (the abbreviation of Tangent can be 'tg' as well)
+ */
+ template<class ValueType>
+ ValueType Tg(const ValueType & x, ErrorCode * err = 0)
+ {
+ return Tan(x, err);
+ }
+
+
+ /*!
+ this function calulates the Cotangent
+ we're using the formula tan(x) = cos(x) / sin(x)
+
+ (why do we make it in this way?
+ look at information in Tan() function)
+ */
+ template<class ValueType>
+ ValueType Cot(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType result = Sin(x, err);
+
+ if( err && *err != err_ok )
+ return result;
+
+ if( result.IsZero() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ result.SetNan();
+
+ return result;
+ }
+
+ return Cos(x, err) / result;
+ }
+
+
+ /*!
+ this function calulates the Cotangent
+ look at the description of Cot(...)
+
+ (the abbreviation of Cotangent can be 'ctg' as well)
+ */
+ template<class ValueType>
+ ValueType Ctg(const ValueType & x, ErrorCode * err = 0)
+ {
+ return Cot(x, err);
+ }
+
+
+ /*
+ *
+ * inverse trigonometric functions
+ *
+ *
+ */
+
+ namespace auxiliaryfunctions
+ {
+
+ /*!
+ an auxiliary function for calculating the Arc Sine
+
+ we're calculating asin from the following formula:
+ asin(x) = x + (1*x^3)/(2*3) + (1*3*x^5)/(2*4*5) + (1*3*5*x^7)/(2*4*6*7) + ...
+ where abs(x) <= 1
+
+ we're using this formula when x is from <0, 1/2>
+ */
+ template<class ValueType>
+ ValueType ASin_0(const ValueType & x)
+ {
+ ValueType nominator, denominator, nominator_add, nominator_x, denominator_add, denominator_x;
+ ValueType two, result(x), x2(x);
+ ValueType nominator_temp, denominator_temp, old_result = result;
+ uint c = 0;
+
+ x2.Mul(x);
+ two = 2;
+
+ nominator.SetOne();
+ denominator = two;
+ nominator_add = nominator;
+ denominator_add = denominator;
+ nominator_x = x;
+ denominator_x = 3;
+
+ for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+ {
+ c += nominator_x.Mul(x2);
+ nominator_temp = nominator_x;
+ c += nominator_temp.Mul(nominator);
+ denominator_temp = denominator;
+ c += denominator_temp.Mul(denominator_x);
+ c += nominator_temp.Div(denominator_temp);
+
+ // if there is a carry somewhere we only break the calculating
+ // the result should be ok -- it's from <-pi/2, pi/2>
+ if( c )
+ break;
+
+ result.Add(nominator_temp);
+
+ if( result == old_result )
+ // there's no sense to calculate more
+ break;
+
+ old_result = result;
+
+
+ c += nominator_add.Add(two);
+ c += denominator_add.Add(two);
+ c += nominator.Mul(nominator_add);
+ c += denominator.Mul(denominator_add);
+ c += denominator_x.Add(two);
+ }
+
+ return result;
+ }
+
+
+
+ /*!
+ an auxiliary function for calculating the Arc Sine
+
+ we're calculating asin from the following formula:
+ asin(x) = pi/2 - sqrt(2)*sqrt(1-x) * asin_temp
+ asin_temp = 1 + (1*(1-x))/((2*3)*(2)) + (1*3*(1-x)^2)/((2*4*5)*(4)) + (1*3*5*(1-x)^3)/((2*4*6*7)*(8)) + ...
+
+ where abs(x) <= 1
+
+ we're using this formula when x is from (1/2, 1>
+ */
+ template<class ValueType>
+ ValueType ASin_1(const ValueType & x)
+ {
+ ValueType nominator, denominator, nominator_add, nominator_x, nominator_x_add, denominator_add, denominator_x;
+ ValueType denominator2;
+ ValueType one, two, result;
+ ValueType nominator_temp, denominator_temp, old_result;
+ uint c = 0;
+
+ two = 2;
+
+ one.SetOne();
+ nominator = one;
+ result = one;
+ old_result = result;
+ denominator = two;
+ nominator_add = nominator;
+ denominator_add = denominator;
+ nominator_x = one;
+ nominator_x.Sub(x);
+ nominator_x_add = nominator_x;
+ denominator_x = 3;
+ denominator2 = two;
+
+
+ for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+ {
+ nominator_temp = nominator_x;
+ c += nominator_temp.Mul(nominator);
+ denominator_temp = denominator;
+ c += denominator_temp.Mul(denominator_x);
+ c += denominator_temp.Mul(denominator2);
+ c += nominator_temp.Div(denominator_temp);
+
+ // if there is a carry somewhere we only break the calculating
+ // the result should be ok -- it's from <-pi/2, pi/2>
+ if( c )
+ break;
+
+ result.Add(nominator_temp);
+
+ if( result == old_result )
+ // there's no sense to calculate more
+ break;
+
+ old_result = result;
+
+ c += nominator_x.Mul(nominator_x_add);
+ c += nominator_add.Add(two);
+ c += denominator_add.Add(two);
+ c += nominator.Mul(nominator_add);
+ c += denominator.Mul(denominator_add);
+ c += denominator_x.Add(two);
+ c += denominator2.Mul(two);
+ }
+
+
+ nominator_x_add.exponent.AddOne(); // *2
+ one.exponent.SubOne(); // =0.5
+ nominator_x_add.Pow(one); // =sqrt(nominator_x_add)
+ result.Mul(nominator_x_add);
+
+ one.Set05Pi();
+ one.Sub(result);
+
+ return one;
+ }
+
+
+ } // namespace auxiliaryfunctions
+
+
+ /*!
+ this function calculates the Arc Sine
+ x is from <-1,1>
+ */
+ template<class ValueType>
+ ValueType ASin(ValueType x, ErrorCode * err = 0)
+ {
+ using namespace auxiliaryfunctions;
+
+ ValueType result, one;
+ one.SetOne();
+ bool change_sign = false;
+
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x;
+ }
+
+ if( x.GreaterWithoutSignThan(one) )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return result; // NaN is set by default
+ }
+
+ if( x.IsSign() )
+ {
+ change_sign = true;
+ x.Abs();
+ }
+
+ one.exponent.SubOne(); // =0.5
+
+ // asin(-x) = -asin(x)
+ if( x.GreaterWithoutSignThan(one) )
+ result = ASin_1(x);
+ else
+ result = ASin_0(x);
+
+ if( change_sign )
+ result.ChangeSign();
+
+ if( err )
+ *err = err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ this function calculates the Arc Cosine
+
+ we're using the formula:
+ acos(x) = pi/2 - asin(x)
+ */
+ template<class ValueType>
+ ValueType ACos(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType temp;
+
+ temp.Set05Pi();
+ temp.Sub(ASin(x, err));
+
+ return temp;
+ }
+
+
+
+ namespace auxiliaryfunctions
+ {
+
+ /*!
+ an auxiliary function for calculating the Arc Tangent
+
+ arc tan (x) where x is in <0; 0.5)
+ (x can be in (-0.5 ; 0.5) too)
+
+ we're using the Taylor series expanded in zero:
+ atan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + ...
+ */
+ template<class ValueType>
+ ValueType ATan0(const ValueType & x)
+ {
+ ValueType nominator, denominator, nominator_add, denominator_add, temp;
+ ValueType result, old_result;
+ bool adding = false;
+ uint c = 0;
+
+ result = x;
+ old_result = result;
+ nominator = x;
+ nominator_add = x;
+ nominator_add.Mul(x);
+
+ denominator.SetOne();
+ denominator_add = 2;
+
+ for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+ {
+ c += nominator.Mul(nominator_add);
+ c += denominator.Add(denominator_add);
+
+ temp = nominator;
+ c += temp.Div(denominator);
+
+ if( c )
+ // the result should be ok
+ break;
+
+ if( adding )
+ result.Add(temp);
+ else
+ result.Sub(temp);
+
+ if( result == old_result )
+ // there's no sense to calculate more
+ break;
+
+ old_result = result;
+ adding = !adding;
+ }
+
+ return result;
+ }
+
+
+ /*!
+ an auxiliary function for calculating the Arc Tangent
+
+ where x is in <0 ; 1>
+ */
+ template<class ValueType>
+ ValueType ATan01(const ValueType & x)
+ {
+ ValueType half;
+ half.Set05();
+
+ /*
+ it would be better if we chose about sqrt(2)-1=0.41... instead of 0.5 here
+
+ because as you can see below:
+ when x = sqrt(2)-1
+ abs(x) = abs( (x-1)/(1+x) )
+ so when we're calculating values around x
+ then they will be better converged to each other
+
+ for example if we have x=0.4999 then during calculating ATan0(0.4999)
+ we have to make about 141 iterations but when we have x=0.5
+ then during calculating ATan0( (x-1)/(1+x) ) we have to make
+ only about 89 iterations (both for Big<3,9>)
+
+ in the future this 0.5 can be changed
+ */
+ if( x.SmallerWithoutSignThan(half) )
+ return ATan0(x);
+
+
+ /*
+ x>=0.5 and x<=1
+ (x can be even smaller than 0.5)
+
+ y = atac(x)
+ x = tan(y)
+
+ tan(y-b) = (tan(y)-tab(b)) / (1+tan(y)*tan(b))
+ y-b = atan( (tan(y)-tab(b)) / (1+tan(y)*tan(b)) )
+ y = b + atan( (x-tab(b)) / (1+x*tan(b)) )
+
+ let b = pi/4
+ tan(b) = tan(pi/4) = 1
+ y = pi/4 + atan( (x-1)/(1+x) )
+
+ so
+ atac(x) = pi/4 + atan( (x-1)/(1+x) )
+ when x->1 (x converges to 1) the (x-1)/(1+x) -> 0
+ and we can use ATan0() function here
+ */
+
+ ValueType n(x),d(x),one,result;
+
+ one.SetOne();
+ n.Sub(one);
+ d.Add(one);
+ n.Div(d);
+
+ result = ATan0(n);
+
+ n.Set05Pi();
+ n.exponent.SubOne(); // =pi/4
+ result.Add(n);
+
+ return result;
+ }
+
+
+ /*!
+ an auxiliary function for calculating the Arc Tangent
+ where x > 1
+
+ we're using the formula:
+ atan(x) = pi/2 - atan(1/x) for x>0
+ */
+ template<class ValueType>
+ ValueType ATanGreaterThanPlusOne(const ValueType & x)
+ {
+ ValueType temp, atan;
+
+ temp.SetOne();
+
+ if( temp.Div(x) )
+ {
+ // if there was a carry here that means x is very big
+ // and atan(1/x) fast converged to 0
+ atan.SetZero();
+ }
+ else
+ atan = ATan01(temp);
+
+ temp.Set05Pi();
+ temp.Sub(atan);
+
+ return temp;
+ }
+
+ } // namespace auxiliaryfunctions
+
+
+ /*!
+ this function calculates the Arc Tangent
+ */
+ template<class ValueType>
+ ValueType ATan(ValueType x)
+ {
+ using namespace auxiliaryfunctions;
+
+ ValueType one, result;
+ one.SetOne();
+ bool change_sign = false;
+
+ if( x.IsNan() )
+ return x;
+
+ // if x is negative we're using the formula:
+ // atan(-x) = -atan(x)
+ if( x.IsSign() )
+ {
+ change_sign = true;
+ x.Abs();
+ }
+
+ if( x.GreaterWithoutSignThan(one) )
+ result = ATanGreaterThanPlusOne(x);
+ else
+ result = ATan01(x);
+
+ if( change_sign )
+ result.ChangeSign();
+
+ return result;
+ }
+
+
+ /*!
+ this function calculates the Arc Tangent
+ look at the description of ATan(...)
+
+ (the abbreviation of Arc Tangent can be 'atg' as well)
+ */
+ template<class ValueType>
+ ValueType ATg(const ValueType & x)
+ {
+ return ATan(x);
+ }
+
+
+ /*!
+ this function calculates the Arc Cotangent
+
+ we're using the formula:
+ actan(x) = pi/2 - atan(x)
+ */
+ template<class ValueType>
+ ValueType ACot(const ValueType & x)
+ {
+ ValueType result;
+
+ result.Set05Pi();
+ result.Sub(ATan(x));
+
+ return result;
+ }
+
+
+ /*!
+ this function calculates the Arc Cotangent
+ look at the description of ACot(...)
+
+ (the abbreviation of Arc Cotangent can be 'actg' as well)
+ */
+ template<class ValueType>
+ ValueType ACtg(const ValueType & x)
+ {
+ return ACot(x);
+ }
+
+
+ /*
+ *
+ * hyperbolic functions
+ *
+ *
+ */
+
+
+ /*!
+ this function calculates the Hyperbolic Sine
+
+ we're using the formula sinh(x)= ( e^x - e^(-x) ) / 2
+ */
+ template<class ValueType>
+ ValueType Sinh(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType ex, emx;
+ uint c = 0;
+
+ c += ex.Exp(x);
+ c += emx.Exp(-x);
+
+ c += ex.Sub(emx);
+ c += ex.exponent.SubOne();
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return ex;
+ }
+
+
+ /*!
+ this function calculates the Hyperbolic Cosine
+
+ we're using the formula cosh(x)= ( e^x + e^(-x) ) / 2
+ */
+ template<class ValueType>
+ ValueType Cosh(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType ex, emx;
+ uint c = 0;
+
+ c += ex.Exp(x);
+ c += emx.Exp(-x);
+
+ c += ex.Add(emx);
+ c += ex.exponent.SubOne();
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return ex;
+ }
+
+
+ /*!
+ this function calculates the Hyperbolic Tangent
+
+ we're using the formula tanh(x)= ( e^x - e^(-x) ) / ( e^x + e^(-x) )
+ */
+ template<class ValueType>
+ ValueType Tanh(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType ex, emx, nominator, denominator;
+ uint c = 0;
+
+ c += ex.Exp(x);
+ c += emx.Exp(-x);
+
+ nominator = ex;
+ c += nominator.Sub(emx);
+ denominator = ex;
+ c += denominator.Add(emx);
+
+ c += nominator.Div(denominator);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return nominator;
+ }
+
+
+ /*!
+ this function calculates the Hyperbolic Tangent
+ look at the description of Tanh(...)
+
+ (the abbreviation of Hyperbolic Tangent can be 'tgh' as well)
+ */
+ template<class ValueType>
+ ValueType Tgh(const ValueType & x, ErrorCode * err = 0)
+ {
+ return Tanh(x, err);
+ }
+
+ /*!
+ this function calculates the Hyperbolic Cotangent
+
+ we're using the formula coth(x)= ( e^x + e^(-x) ) / ( e^x - e^(-x) )
+ */
+ template<class ValueType>
+ ValueType Coth(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ if( x.IsZero() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return ValueType(); // NaN is set by default
+ }
+
+ ValueType ex, emx, nominator, denominator;
+ uint c = 0;
+
+ c += ex.Exp(x);
+ c += emx.Exp(-x);
+
+ nominator = ex;
+ c += nominator.Add(emx);
+ denominator = ex;
+ c += denominator.Sub(emx);
+
+ c += nominator.Div(denominator);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return nominator;
+ }
+
+
+ /*!
+ this function calculates the Hyperbolic Cotangent
+ look at the description of Coth(...)
+
+ (the abbreviation of Hyperbolic Cotangent can be 'ctgh' as well)
+ */
+ template<class ValueType>
+ ValueType Ctgh(const ValueType & x, ErrorCode * err = 0)
+ {
+ return Coth(x, err);
+ }
+
+
+ /*
+ *
+ * inverse hyperbolic functions
+ *
+ *
+ */
+
+
+ /*!
+ inverse hyperbolic sine
+
+ asinh(x) = ln( x + sqrt(x^2 + 1) )
+ */
+ template<class ValueType>
+ ValueType ASinh(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType xx(x), one, result;
+ uint c = 0;
+ one.SetOne();
+
+ c += xx.Mul(x);
+ c += xx.Add(one);
+ one.exponent.SubOne(); // one=0.5
+ // xx is >= 1
+ c += xx.PowFrac(one); // xx=sqrt(xx)
+ c += xx.Add(x);
+ c += result.Ln(xx); // xx > 0
+
+ // here can only be a carry
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ inverse hyperbolic cosine
+
+ acosh(x) = ln( x + sqrt(x^2 - 1) ) x in <1, infinity)
+ */
+ template<class ValueType>
+ ValueType ACosh(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType xx(x), one, result;
+ uint c = 0;
+ one.SetOne();
+
+ if( x < one )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return result; // NaN is set by default
+ }
+
+ c += xx.Mul(x);
+ c += xx.Sub(one);
+ // xx is >= 0
+ // we can't call a PowFrac when the 'x' is zero
+ // if x is 0 the sqrt(0) is 0
+ if( !xx.IsZero() )
+ {
+ one.exponent.SubOne(); // one=0.5
+ c += xx.PowFrac(one); // xx=sqrt(xx)
+ }
+ c += xx.Add(x);
+ c += result.Ln(xx); // xx >= 1
+
+ // here can only be a carry
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ inverse hyperbolic tangent
+
+ atanh(x) = 0.5 * ln( (1+x) / (1-x) ) x in (-1, 1)
+ */
+ template<class ValueType>
+ ValueType ATanh(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType nominator(x), denominator, one, result;
+ uint c = 0;
+ one.SetOne();
+
+ if( !x.SmallerWithoutSignThan(one) )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return result; // NaN is set by default
+ }
+
+ c += nominator.Add(one);
+ denominator = one;
+ c += denominator.Sub(x);
+ c += nominator.Div(denominator);
+ c += result.Ln(nominator);
+ c += result.exponent.SubOne();
+
+ // here can only be a carry
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ inverse hyperbolic tantent
+ */
+ template<class ValueType>
+ ValueType ATgh(const ValueType & x, ErrorCode * err = 0)
+ {
+ return ATanh(x, err);
+ }
+
+
+ /*!
+ inverse hyperbolic cotangent
+
+ acoth(x) = 0.5 * ln( (x+1) / (x-1) ) x in (-infinity, -1) or (1, infinity)
+ */
+ template<class ValueType>
+ ValueType ACoth(const ValueType & x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x; // NaN
+ }
+
+ ValueType nominator(x), denominator(x), one, result;
+ uint c = 0;
+ one.SetOne();
+
+ if( !x.GreaterWithoutSignThan(one) )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return result; // NaN is set by default
+ }
+
+ c += nominator.Add(one);
+ c += denominator.Sub(one);
+ c += nominator.Div(denominator);
+ c += result.Ln(nominator);
+ c += result.exponent.SubOne();
+
+ // here can only be a carry
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ inverse hyperbolic cotantent
+ */
+ template<class ValueType>
+ ValueType ACtgh(const ValueType & x, ErrorCode * err = 0)
+ {
+ return ACoth(x, err);
+ }
+
+
+
+
+
+ /*
+ *
+ * functions for converting between degrees, radians and gradians
+ *
+ *
+ */
+
+
+ /*!
+ this function converts degrees to radians
+
+ it returns: x * pi / 180
+ */
+ template<class ValueType>
+ ValueType DegToRad(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType result, temp;
+ uint c = 0;
+
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x;
+ }
+
+ result = x;
+
+ // it is better to make division first and then multiplication
+ // the result is more accurate especially when x is: 90,180,270 or 360
+ temp = 180;
+ c += result.Div(temp);
+
+ temp.SetPi();
+ c += result.Mul(temp);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ this function converts radians to degrees
+
+ it returns: x * 180 / pi
+ */
+ template<class ValueType>
+ ValueType RadToDeg(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType result, delimiter;
+ uint c = 0;
+
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x;
+ }
+
+ result = 180;
+ c += result.Mul(x);
+
+ delimiter.SetPi();
+ c += result.Div(delimiter);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ this function converts degrees in the long format into one value
+
+ long format: (degrees, minutes, seconds)
+ minutes and seconds must be greater than or equal zero
+
+ result:
+ if d>=0 : result= d + ((s/60)+m)/60
+ if d<0 : result= d - ((s/60)+m)/60
+
+ ((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because
+ there's only one division)
+
+ for example:
+ DegToDeg(10, 30, 0) = 10.5
+ DegToDeg(10, 24, 35.6)=10.4098(8)
+ */
+ template<class ValueType>
+ ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s,
+ ErrorCode * err = 0)
+ {
+ ValueType delimiter, multipler;
+ uint c = 0;
+
+ if( d.IsNan() || m.IsNan() || s.IsNan() || m.IsSign() || s.IsSign() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ delimiter.SetZeroNan(); // not needed, only to get rid of GCC warning about an uninitialized variable
+
+ return delimiter;
+ }
+
+ multipler = 60;
+ delimiter = 3600;
+
+ c += multipler.Mul(m);
+ c += multipler.Add(s);
+ c += multipler.Div(delimiter);
+
+ if( d.IsSign() )
+ multipler.ChangeSign();
+
+ c += multipler.Add(d);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return multipler;
+ }
+
+
+ /*!
+ this function converts degrees in the long format to radians
+ */
+ template<class ValueType>
+ ValueType DegToRad( const ValueType & d, const ValueType & m, const ValueType & s,
+ ErrorCode * err = 0)
+ {
+ ValueType temp_deg = DegToDeg(d,m,s,err);
+
+ if( err && *err!=err_ok )
+ return temp_deg;
+
+ return DegToRad(temp_deg, err);
+ }
+
+
+ /*!
+ this function converts gradians to radians
+
+ it returns: x * pi / 200
+ */
+ template<class ValueType>
+ ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType result, temp;
+ uint c = 0;
+
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x;
+ }
+
+ result = x;
+
+ // it is better to make division first and then multiplication
+ // the result is more accurate especially when x is: 100,200,300 or 400
+ temp = 200;
+ c += result.Div(temp);
+
+ temp.SetPi();
+ c += result.Mul(temp);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ this function converts radians to gradians
+
+ it returns: x * 200 / pi
+ */
+ template<class ValueType>
+ ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType result, delimiter;
+ uint c = 0;
+
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x;
+ }
+
+ result = 200;
+ c += result.Mul(x);
+
+ delimiter.SetPi();
+ c += result.Div(delimiter);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ this function converts degrees to gradians
+
+ it returns: x * 200 / 180
+ */
+ template<class ValueType>
+ ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType result, temp;
+ uint c = 0;
+
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x;
+ }
+
+ result = x;
+
+ temp = 200;
+ c += result.Mul(temp);
+
+ temp = 180;
+ c += result.Div(temp);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+ /*!
+ this function converts degrees in the long format to gradians
+ */
+ template<class ValueType>
+ ValueType DegToGrad( const ValueType & d, const ValueType & m, const ValueType & s,
+ ErrorCode * err = 0)
+ {
+ ValueType temp_deg = DegToDeg(d,m,s,err);
+
+ if( err && *err!=err_ok )
+ return temp_deg;
+
+ return DegToGrad(temp_deg, err);
+ }
+
+
+ /*!
+ this function converts degrees to gradians
+
+ it returns: x * 180 / 200
+ */
+ template<class ValueType>
+ ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
+ {
+ ValueType result, temp;
+ uint c = 0;
+
+ if( x.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return x;
+ }
+
+ result = x;
+
+ temp = 180;
+ c += result.Mul(temp);
+
+ temp = 200;
+ c += result.Div(temp);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return result;
+ }
+
+
+
+
+ /*
+ *
+ * another functions
+ *
+ *
+ */
+
+
+ /*!
+ this function calculates the square root
+
+ Sqrt(9) = 3
+ */
+ template<class ValueType>
+ ValueType Sqrt(ValueType x, ErrorCode * err = 0)
+ {
+ if( x.IsNan() || x.IsSign() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ x.SetNan();
+
+ return x;
+ }
+
+ uint c = x.Sqrt();
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return x;
+ }
+
+
+
+ namespace auxiliaryfunctions
+ {
+
+ template<class ValueType>
+ bool RootCheckIndexSign(ValueType & x, const ValueType & index, ErrorCode * err)
+ {
+ if( index.IsSign() )
+ {
+ // index cannot be negative
+ if( err )
+ *err = err_improper_argument;
+
+ x.SetNan();
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ template<class ValueType>
+ bool RootCheckIndexZero(ValueType & x, const ValueType & index, ErrorCode * err)
+ {
+ if( index.IsZero() )
+ {
+ if( x.IsZero() )
+ {
+ // there isn't root(0;0) - we assume it's not defined
+ if( err )
+ *err = err_improper_argument;
+
+ x.SetNan();
+
+ return true;
+ }
+
+ // root(x;0) is 1 (if x!=0)
+ x.SetOne();
+
+ if( err )
+ *err = err_ok;
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ template<class ValueType>
+ bool RootCheckIndexOne(const ValueType & index, ErrorCode * err)
+ {
+ ValueType one;
+ one.SetOne();
+
+ if( index == one )
+ {
+ //root(x;1) is x
+ // we do it because if we used the PowFrac function
+ // we would lose the precision
+ if( err )
+ *err = err_ok;
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ template<class ValueType>
+ bool RootCheckIndexTwo(ValueType & x, const ValueType & index, ErrorCode * err)
+ {
+ if( index == 2 )
+ {
+ x = Sqrt(x, err);
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ template<class ValueType>
+ bool RootCheckIndexFrac(ValueType & x, const ValueType & index, ErrorCode * err)
+ {
+ if( !index.IsInteger() )
+ {
+ // index must be integer
+ if( err )
+ *err = err_improper_argument;
+
+ x.SetNan();
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ template<class ValueType>
+ bool RootCheckXZero(ValueType & x, ErrorCode * err)
+ {
+ if( x.IsZero() )
+ {
+ // root(0;index) is zero (if index!=0)
+ // RootCheckIndexZero() must be called beforehand
+ x.SetZero();
+
+ if( err )
+ *err = err_ok;
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ template<class ValueType>
+ bool RootCheckIndex(ValueType & x, const ValueType & index, ErrorCode * err, bool * change_sign)
+ {
+ *change_sign = false;
+
+ if( index.Mod2() )
+ {
+ // index is odd (1,3,5...)
+ if( x.IsSign() )
+ {
+ *change_sign = true;
+ x.Abs();
+ }
+ }
+ else
+ {
+ // index is even
+ // x cannot be negative
+ if( x.IsSign() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ x.SetNan();
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ template<class ValueType>
+ uint RootCorrectInteger(ValueType & old_x, ValueType & x, const ValueType & index)
+ {
+ if( !old_x.IsInteger() || x.IsInteger() || !index.exponent.IsSign() )
+ return 0;
+
+ // old_x is integer,
+ // x is not integer,
+ // index is relatively small (index.exponent<0 or index.exponent<=0)
+ // (because we're using a special powering algorithm Big::PowUInt())
+
+ uint c = 0;
+
+ ValueType temp(x);
+ c += temp.Round();
+
+ ValueType temp_round(temp);
+ c += temp.PowUInt(index);
+
+ if( temp == old_x )
+ x = temp_round;
+
+ return (c==0)? 0 : 1;
+ }
+
+
+
+ } // namespace auxiliaryfunctions
+
+
+
+ /*!
+ indexth Root of x
+ index must be integer and not negative <0;1;2;3....)
+
+ if index==0 the result is one
+ if x==0 the result is zero and we assume root(0;0) is not defined
+
+ if index is even (2;4;6...) the result is x^(1/index) and x>0
+ if index is odd (1;2;3;...) the result is either
+ -(abs(x)^(1/index)) if x<0 or
+ x^(1/index)) if x>0
+
+ (for index==1 the result is equal x)
+ */
+ template<class ValueType>
+ ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
+ {
+ using namespace auxiliaryfunctions;
+
+ if( x.IsNan() || index.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ x.SetNan();
+
+ return x;
+ }
+
+ if( RootCheckIndexSign(x, index, err) ) return x;
+ if( RootCheckIndexZero(x, index, err) ) return x;
+ if( RootCheckIndexOne ( index, err) ) return x;
+ if( RootCheckIndexTwo (x, index, err) ) return x;
+ if( RootCheckIndexFrac(x, index, err) ) return x;
+ if( RootCheckXZero (x, err) ) return x;
+
+ // index integer and index!=0
+ // x!=0
+
+ ValueType old_x(x);
+ bool change_sign;
+
+ if( RootCheckIndex(x, index, err, &change_sign ) ) return x;
+
+ ValueType temp;
+ uint c = 0;
+
+ // we're using the formula: root(x ; n) = exp( ln(x) / n )
+ c += temp.Ln(x);
+ c += temp.Div(index);
+ c += x.Exp(temp);
+
+ if( change_sign )
+ {
+ // x is different from zero
+ x.SetSign();
+ }
+
+ c += RootCorrectInteger(old_x, x, index);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return x;
+ }
+
+
+
+ /*!
+ absolute value of x
+ e.g. -2 = 2
+ 2 = 2
+ */
+ template<class ValueType>
+ ValueType Abs(const ValueType & x)
+ {
+ ValueType result( x );
+ result.Abs();
+
+ return result;
+ }
+
+
+ /*!
+ it returns the sign of the value
+ e.g. -2 = -1
+ 0 = 0
+ 10 = 1
+ */
+ template<class ValueType>
+ ValueType Sgn(ValueType x)
+ {
+ x.Sgn();
+
+ return x;
+ }
+
+
+ /*!
+ the remainder from a division
+
+ e.g.
+ mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6
+ mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
+ mod( 12.6 ; -3) = 0.6
+ mod(-12.6 ; -3) = -0.6
+ */
+ template<class ValueType>
+ ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
+ {
+ if( a.IsNan() || b.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ a.SetNan();
+
+ return a;
+ }
+
+ uint c = a.Mod(b);
+
+ if( err )
+ *err = c ? err_overflow : err_ok;
+
+ return a;
+ }
+
+
+
+ namespace auxiliaryfunctions
+ {
+
+ /*!
+ this function is used to store factorials in a given container
+ 'more' means how many values should be added at the end
+
+ e.g.
+ std::vector<ValueType> fact;
+ SetFactorialSequence(fact, 3);
+ // now the container has three values: 1 1 2
+
+ SetFactorialSequence(fact, 2);
+ // now the container has five values: 1 1 2 6 24
+ */
+ template<class ValueType>
+ void SetFactorialSequence(std::vector<ValueType> & fact, uint more = 20)
+ {
+ if( more == 0 )
+ more = 1;
+
+ uint start = static_cast<uint>(fact.size());
+ fact.resize(fact.size() + more);
+
+ if( start == 0 )
+ {
+ fact[0] = 1;
+ ++start;
+ }
+
+ for(uint i=start ; i<fact.size() ; ++i)
+ {
+ fact[i] = fact[i-1];
+ fact[i].MulInt(i);
+ }
+ }
+
+
+ /*!
+ an auxiliary function used to calculate Bernoulli numbers
+
+ this function returns a sum:
+ sum(m) = sum_{k=0}^{m-1} {2^k * (m k) * B(k)} k in [0, m-1] (m k) means binomial coefficient = (m! / (k! * (m-k)!))
+
+ you should have sufficient factorials in cgamma.fact
+ (cgamma.fact should have at least m items)
+
+ n_ should be equal 2
+ */
+ template<class ValueType>
+ ValueType SetBernoulliNumbersSum(CGamma<ValueType> & cgamma, const ValueType & n_, uint m,
+ const volatile StopCalculating * stop = 0)
+ {
+ ValueType k_, temp, temp2, temp3, sum;
+
+ sum.SetZero();
+
+ for(uint k=0 ; k<m ; ++k) // k<m means k<=m-1
+ {
+ if( stop && (k & 15)==0 ) // means: k % 16 == 0
+ if( stop->WasStopSignal() )
+ return ValueType(); // NaN
+
+ if( k>1 && (k & 1) == 1 ) // for that k the Bernoulli number is zero
+ continue;
+
+ k_ = k;
+
+ temp = n_; // n_ is equal 2
+ temp.Pow(k_);
+ // temp = 2^k
+
+ temp2 = cgamma.fact[m];
+ temp3 = cgamma.fact[k];
+ temp3.Mul(cgamma.fact[m-k]);
+ temp2.Div(temp3);
+ // temp2 = (m k) = m! / ( k! * (m-k)! )
+
+ temp.Mul(temp2);
+ temp.Mul(cgamma.bern[k]);
+
+ sum.Add(temp);
+ // sum += 2^k * (m k) * B(k)
+
+ if( sum.IsNan() )
+ break;
+ }
+
+ return sum;
+ }
+
+
+ /*!
+ an auxiliary function used to calculate Bernoulli numbers
+ start is >= 2
+
+ we use the recurrence formula:
+ B(m) = 1 / (2*(1 - 2^m)) * sum(m)
+ where sum(m) is calculated by SetBernoulliNumbersSum()
+ */
+ template<class ValueType>
+ bool SetBernoulliNumbersMore(CGamma<ValueType> & cgamma, uint start, const volatile StopCalculating * stop = 0)
+ {
+ ValueType denominator, temp, temp2, temp3, m_, sum, sum2, n_, k_;
+
+ const uint n = 2;
+ n_ = n;
+
+ // start is >= 2
+ for(uint m=start ; m<cgamma.bern.size() ; ++m)
+ {
+ if( (m & 1) == 1 )
+ {
+ cgamma.bern[m].SetZero();
+ }
+ else
+ {
+ m_ = m;
+
+ temp = n_; // n_ = 2
+ temp.Pow(m_);
+ // temp = 2^m
+
+ denominator.SetOne();
+ denominator.Sub(temp);
+ if( denominator.exponent.AddOne() ) // it means: denominator.MulInt(2)
+ denominator.SetNan();
+
+ // denominator = 2 * (1 - 2^m)
+
+ cgamma.bern[m] = SetBernoulliNumbersSum(cgamma, n_, m, stop);
+
+ if( stop && stop->WasStopSignal() )
+ {
+ cgamma.bern.resize(m); // valid numbers are in [0, m-1]
+ return false;
+ }
+
+ cgamma.bern[m].Div(denominator);
+ }
+ }
+
+ return true;
+ }
+
+
+ /*!
+ this function is used to calculate Bernoulli numbers,
+ returns false if there was a stop signal,
+ 'more' means how many values should be added at the end
+
+ e.g.
+ typedef Big<1,2> MyBig;
+ CGamma<MyBig> cgamma;
+ SetBernoulliNumbers(cgamma, 3);
+ // now we have three first Bernoulli numbers: 1 -0.5 0.16667
+
+ SetBernoulliNumbers(cgamma, 4);
+ // now we have 7 Bernoulli numbers: 1 -0.5 0.16667 0 -0.0333 0 0.0238
+ */
+ template<class ValueType>
+ bool SetBernoulliNumbers(CGamma<ValueType> & cgamma, uint more = 20, const volatile StopCalculating * stop = 0)
+ {
+ if( more == 0 )
+ more = 1;
+
+ uint start = static_cast<uint>(cgamma.bern.size());
+ cgamma.bern.resize(cgamma.bern.size() + more);
+
+ if( start == 0 )
+ {
+ cgamma.bern[0].SetOne();
+ ++start;
+ }
+
+ if( cgamma.bern.size() == 1 )
+ return true;
+
+ if( start == 1 )
+ {
+ cgamma.bern[1].Set05();
+ cgamma.bern[1].ChangeSign();
+ ++start;
+ }
+
+ // we should have sufficient factorials in cgamma.fact
+ if( cgamma.fact.size() < cgamma.bern.size() )
+ SetFactorialSequence(cgamma.fact, static_cast<uint>(cgamma.bern.size() - cgamma.fact.size()));
+
+
+ return SetBernoulliNumbersMore(cgamma, start, stop);
+ }
+
+
+ /*!
+ an auxiliary function used to calculate the Gamma() function
+
+ we calculate a sum:
+ sum(n) = sum_{m=2} { B(m) / ( (m^2 - m) * n^(m-1) ) } = 1/(12*n) - 1/(360*n^3) + 1/(1260*n^5) + ...
+ B(m) means a mth Bernoulli number
+ the sum starts from m=2, we calculate as long as the value will not change after adding a next part
+ */
+ template<class ValueType>
+ ValueType GammaFactorialHighSum(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
+ const volatile StopCalculating * stop)
+ {
+ ValueType temp, temp2, denominator, sum, oldsum;
+
+ sum.SetZero();
+
+ for(uint m=2 ; m<TTMATH_ARITHMETIC_MAX_LOOP ; m+=2)
+ {
+ if( stop && (m & 3)==0 ) // (m & 3)==0 means: (m % 4)==0
+ if( stop->WasStopSignal() )
+ {
+ err = err_interrupt;
+ return ValueType(); // NaN
+ }
+
+ temp = (m-1);
+ denominator = n;
+ denominator.Pow(temp);
+ // denominator = n ^ (m-1)
+
+ temp = m;
+ temp2 = temp;
+ temp.Mul(temp2);
+ temp.Sub(temp2);
+ // temp = m^2 - m
+
+ denominator.Mul(temp);
+ // denominator = (m^2 - m) * n ^ (m-1)
+
+ if( m >= cgamma.bern.size() )
+ {
+ if( !SetBernoulliNumbers(cgamma, m - cgamma.bern.size() + 1 + 3, stop) ) // 3 more than needed
+ {
+ // there was the stop signal
+ err = err_interrupt;
+ return ValueType(); // NaN
+ }
+ }
+
+ temp = cgamma.bern[m];
+ temp.Div(denominator);
+
+ oldsum = sum;
+ sum.Add(temp);
+
+ if( sum.IsNan() || oldsum==sum )
+ break;
+ }
+
+ return sum;
+ }
+
+
+ /*!
+ an auxiliary function used to calculate the Gamma() function
+
+ we calculate a helper function GammaFactorialHigh() by using Stirling's series:
+ n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) )
+ where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY)
+ and sum(n) is calculated by GammaFactorialHighSum()
+ */
+ template<class ValueType>
+ ValueType GammaFactorialHigh(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
+ const volatile StopCalculating * stop)
+ {
+ ValueType temp, temp2, temp3, denominator, sum;
+
+ temp.Set2Pi();
+ temp.Mul(n);
+ temp2 = Sqrt(temp);
+ // temp2 = sqrt(2*pi*n)
+
+ temp = n;
+ temp3.SetE();
+ temp.Div(temp3);
+ temp.Pow(n);
+ // temp = (n/e)^n
+
+ sum = GammaFactorialHighSum(n, cgamma, err, stop);
+ temp3.Exp(sum);
+ // temp3 = exp(sum)
+
+ temp.Mul(temp2);
+ temp.Mul(temp3);
+
+ return temp;
+ }
+
+
+ /*!
+ an auxiliary function used to calculate the Gamma() function
+
+ Gamma(x) = GammaFactorialHigh(x-1)
+ */
+ template<class ValueType>
+ ValueType GammaPlusHigh(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
+ {
+ ValueType one;
+
+ one.SetOne();
+ n.Sub(one);
+
+ return GammaFactorialHigh(n, cgamma, err, stop);
+ }
+
+
+ /*!
+ an auxiliary function used to calculate the Gamma() function
+
+ we use this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
+ we use the formula:
+ gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1)
+ */
+ template<class ValueType>
+ ValueType GammaPlusLowIntegerInt(uint n, CGamma<ValueType> & cgamma)
+ {
+ TTMATH_ASSERT( n > 0 )
+
+ if( n - 1 < static_cast<uint>(cgamma.fact.size()) )
+ return cgamma.fact[n - 1];
+
+ ValueType res;
+ uint start = 2;
+
+ if( cgamma.fact.size() < 2 )
+ {
+ res.SetOne();
+ }
+ else
+ {
+ start = static_cast<uint>(cgamma.fact.size());
+ res = cgamma.fact[start-1];
+ }
+
+ for(uint i=start ; i<n ; ++i)
+ res.MulInt(i);
+
+ return res;
+ }
+
+
+ /*!
+ an auxiliary function used to calculate the Gamma() function
+
+ we use this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
+ */
+ template<class ValueType>
+ ValueType GammaPlusLowInteger(const ValueType & n, CGamma<ValueType> & cgamma)
+ {
+ sint n_;
+
+ n.ToInt(n_);
+
+ return GammaPlusLowIntegerInt(n_, cgamma);
+ }
+
+
+ /*!
+ an auxiliary function used to calculate the Gamma() function
+
+ we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
+ we use a recurrence formula:
+ gamma(z+1) = z * gamma(z)
+ then: gamma(z) = gamma(z+1) / z
+
+ e.g.
+ gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 )
+ */
+ template<class ValueType>
+ ValueType GammaPlusLow(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
+ {
+ ValueType one, denominator, temp, boundary;
+
+ if( n.IsInteger() )
+ return GammaPlusLowInteger(n, cgamma);
+
+ one.SetOne();
+ denominator = n;
+ boundary = TTMATH_GAMMA_BOUNDARY;
+
+ while( n < boundary )
+ {
+ n.Add(one);
+ denominator.Mul(n);
+ }
+
+ n.Add(one);
+
+ // now n is sufficient big
+ temp = GammaPlusHigh(n, cgamma, err, stop);
+ temp.Div(denominator);
+
+ return temp;
+ }
+
+
+ /*!
+ an auxiliary function used to calculate the Gamma() function
+ */
+ template<class ValueType>
+ ValueType GammaPlus(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
+ {
+ if( n > TTMATH_GAMMA_BOUNDARY )
+ return GammaPlusHigh(n, cgamma, err, stop);
+
+ return GammaPlusLow(n, cgamma, err, stop);
+ }
+
+
+ /*!
+ an auxiliary function used to calculate the Gamma() function
+
+ this function is used when n is negative
+ we use the reflection formula:
+ gamma(1-z) * gamma(z) = pi / sin(pi*z)
+ then: gamma(z) = pi / (sin(pi*z) * gamma(1-z))
+
+ */
+ template<class ValueType>
+ ValueType GammaMinus(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
+ {
+ ValueType pi, denominator, temp, temp2;
+
+ if( n.IsInteger() )
+ {
+ // gamma function is not defined when n is negative and integer
+ err = err_improper_argument;
+ return temp; // NaN
+ }
+
+ pi.SetPi();
+
+ temp = pi;
+ temp.Mul(n);
+ temp2 = Sin(temp);
+ // temp2 = sin(pi * n)
+
+ temp.SetOne();
+ temp.Sub(n);
+ temp = GammaPlus(temp, cgamma, err, stop);
+ // temp = gamma(1 - n)
+
+ temp.Mul(temp2);
+ pi.Div(temp);
+
+ return pi;
+ }
+
+ } // namespace auxiliaryfunctions
+
+
+
+ /*!
+ this function calculates the Gamma function
+
+ it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma()
+ e.g.
+ typedef Big<1,2> MyBig;
+ MyBig x=234, y=345.53;
+ CGamma<MyBig> cgamma;
+ std::cout << Gamma(x, cgamma) << std::endl;
+ std::cout << Gamma(y, cgamma) << std::endl;
+ in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
+ and they will be reused in next calls to the function
+
+ each thread should have its own CGamma<> object, and you can use these objects with Factorial() function too
+ */
+ template<class ValueType>
+ ValueType Gamma(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode * err = 0,
+ const volatile StopCalculating * stop = 0)
+ {
+ using namespace auxiliaryfunctions;
+
+ ValueType result;
+ ErrorCode err_tmp;
+
+ if( n.IsNan() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ return n;
+ }
+
+ if( cgamma.history.Get(n, result, err_tmp) )
+ {
+ if( err )
+ *err = err_tmp;
+
+ return result;
+ }
+
+ err_tmp = err_ok;
+
+ if( n.IsSign() )
+ {
+ result = GammaMinus(n, cgamma, err_tmp, stop);
+ }
+ else
+ if( n.IsZero() )
+ {
+ err_tmp = err_improper_argument;
+ result.SetNan();
+ }
+ else
+ {
+ result = GammaPlus(n, cgamma, err_tmp, stop);
+ }
+
+ if( result.IsNan() && err_tmp==err_ok )
+ err_tmp = err_overflow;
+
+ if( err )
+ *err = err_tmp;
+
+ if( stop && !stop->WasStopSignal() )
+ cgamma.history.Add(n, result, err_tmp);
+
+ return result;
+ }
+
+
+ /*!
+ this function calculates the Gamma function
+
+ note: this function should be used only in a single-thread environment
+ */
+ template<class ValueType>
+ ValueType Gamma(const ValueType & n, ErrorCode * err = 0)
+ {
+ // warning: this static object is not thread safe
+ static CGamma<ValueType> cgamma;
+
+ return Gamma(n, cgamma, err);
+ }
+
+
+
+ namespace auxiliaryfunctions
+ {
+
+ /*!
+ an auxiliary function for calculating the factorial function
+
+ we use the formula:
+ x! = gamma(x+1)
+ */
+ template<class ValueType>
+ ValueType Factorial2(ValueType x,
+ CGamma<ValueType> * cgamma = 0,
+ ErrorCode * err = 0,
+ const volatile StopCalculating * stop = 0)
+ {
+ ValueType result, one;
+
+ if( x.IsNan() || x.IsSign() || !x.IsInteger() )
+ {
+ if( err )
+ *err = err_improper_argument;
+
+ x.SetNan();
+
+ return x;
+ }
+
+ one.SetOne();
+ x.Add(one);
+
+ if( cgamma )
+ return Gamma(x, *cgamma, err, stop);
+
+ return Gamma(x, err);
+ }
+
+ } // namespace auxiliaryfunctions
+
+
+
+ /*!
+ the factorial from given 'x'
+ e.g.
+ Factorial(4) = 4! = 1*2*3*4
+
+ it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial()
+ e.g.
+ typedef Big<1,2> MyBig;
+ MyBig x=234, y=54345;
+ CGamma<MyBig> cgamma;
+ std::cout << Factorial(x, cgamma) << std::endl;
+ std::cout << Factorial(y, cgamma) << std::endl;
+ in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
+ and they will be reused in next calls to the function
+
+ each thread should have its own CGamma<> object, and you can use these objects with Gamma() function too
+ */
+ template<class ValueType>
+ ValueType Factorial(const ValueType & x, CGamma<ValueType> & cgamma, ErrorCode * err = 0,
+ const volatile StopCalculating * stop = 0)
+ {
+ return auxiliaryfunctions::Factorial2(x, &cgamma, err, stop);
+ }
+
+
+ /*!
+ the factorial from given 'x'
+ e.g.
+ Factorial(4) = 4! = 1*2*3*4
+
+ note: this function should be used only in a single-thread environment
+ */
+ template<class ValueType>
+ ValueType Factorial(const ValueType & x, ErrorCode * err = 0)
+ {
+ return auxiliaryfunctions::Factorial2(x, (CGamma<ValueType>*)0, err, 0);
+ }
+
+
+ /*!
+ this method prepares some coefficients: factorials and Bernoulli numbers
+ stored in 'fact' and 'bern' objects
+
+ we're defining the method here because we're using Gamma() function which
+ is not available in ttmathobjects.h
+
+ read the doc info in ttmathobjects.h file where CGamma<> struct is declared
+ */
+ template<class ValueType>
+ void CGamma<ValueType>::InitAll()
+ {
+ ValueType x = TTMATH_GAMMA_BOUNDARY + 1;
+
+ // history.Remove(x) removes only one object
+ // we must be sure that there are not others objects with the key 'x'
+ while( history.Remove(x) )
+ {
+ }
+
+ // the simplest way to initialize is to call the Gamma function with (TTMATH_GAMMA_BOUNDARY + 1)
+ // when x is larger then fewer coefficients we need
+ Gamma(x, *this);
+ }
+
+
+
+} // namespace
+
+
+/*!
+ this is for convenience for the user
+ he can only use '#include <ttmath/ttmath.h>' even if he uses the parser
+*/
+#include "ttmathparser.h"
+
+
+#ifdef _MSC_VER
+//warning C4127: conditional expression is constant
+#pragma warning( default: 4127 )
+//warning C4702: unreachable code
+#pragma warning( default: 4702 )
+//warning C4800: forcing value to bool 'true' or 'false' (performance warning)
+#pragma warning( default: 4800 )
+#endif
+
+#endif
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathbig.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathbig.h
new file mode 100644
index 0000000..dc3e98c
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathbig.h
@@ -0,0 +1,6064 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2011, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef headerfilettmathbig
+#define headerfilettmathbig
+
+/*!
+ \file ttmathbig.h
+ \brief A Class for representing floating point numbers
+*/
+
+#include "ttmathint.h"
+#include "ttmaththreads.h"
+
+#include <iostream>
+
+#ifdef TTMATH_MULTITHREADS
+#include <signal.h>
+#endif
+
+namespace ttmath
+{
+
+
+/*!
+ \brief Big implements the floating point numbers
+*/
+template <uint exp, uint man>
+class Big
+{
+
+/*
+ value = mantissa * 2^exponent
+
+ exponent - an integer value with a sign
+ mantissa - an integer value without a sing
+
+ mantissa must be pushed into the left side that is the highest bit from
+ mantissa must be one (of course if there's another value than zero) -- this job
+ (pushing bits into the left side) making Standardizing() method
+
+ for example:
+ if we want to store value one (1) into our Big object we must:
+ set mantissa to 1
+ set exponent to 0
+ set info to 0
+ and call method Standardizing()
+*/
+
+
+public:
+
+Int<exp> exponent;
+UInt<man> mantissa;
+unsigned char info;
+
+
+/*!
+ Sign
+ the mask of a bit from 'info' which means that there is a sign
+ (when the bit is set)
+*/
+#define TTMATH_BIG_SIGN 128
+
+
+/*!
+ Not a number
+ if this bit is set that there is not a valid number
+*/
+#define TTMATH_BIG_NAN 64
+
+
+/*!
+ Zero
+ if this bit is set that there is value zero
+ mantissa should be zero and exponent should be zero too
+ (the Standardizing() method does this)
+*/
+#define TTMATH_BIG_ZERO 32
+
+
+ /*!
+ this method sets NaN if there was a carry (and returns 1 in such a case)
+
+ c can be 0, 1 or other value different from zero
+ */
+ uint CheckCarry(uint c)
+ {
+ if( c != 0 )
+ {
+ SetNan();
+ return 1;
+ }
+
+ return 0;
+ }
+
+public:
+
+
+ /*!
+ returning the string represents the currect type of the library
+ we have following types:
+ asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
+ asm_gcc_32 - with asm code designed for GCC (32 bits)
+ asm_vc_64 - with asm for VC (64 bit)
+ asm_gcc_64 - with asm for GCC (64 bit)
+ no_asm_32 - pure C++ version (32 bit) - without any asm code
+ no_asm_64 - pure C++ version (64 bit) - without any asm code
+ */
+ static const char * LibTypeStr()
+ {
+ return UInt<man>::LibTypeStr();
+ }
+
+
+ /*!
+ returning the currect type of the library
+ */
+ static LibTypeCode LibType()
+ {
+ return UInt<man>::LibType();
+ }
+
+
+
+ /*!
+ this method moves all bits from mantissa into its left side
+ (suitably changes the exponent) or if the mantissa is zero
+ it sets the exponent to zero as well
+ (and clears the sign bit and sets the zero bit)
+
+ it can return a carry
+ the carry will be when we don't have enough space in the exponent
+
+ you don't have to use this method if you don't change the mantissa
+ and exponent directly
+ */
+ uint Standardizing()
+ {
+ if( mantissa.IsTheHighestBitSet() )
+ {
+ ClearInfoBit(TTMATH_BIG_ZERO);
+ return 0;
+ }
+
+ if( CorrectZero() )
+ return 0;
+
+ uint comp = mantissa.CompensationToLeft();
+
+ return exponent.Sub( comp );
+ }
+
+
+private:
+
+ /*!
+ if the mantissa is equal zero this method sets exponent to zero and
+ info without the sign
+
+ it returns true if there was the correction
+ */
+ bool CorrectZero()
+ {
+ if( mantissa.IsZero() )
+ {
+ SetInfoBit(TTMATH_BIG_ZERO);
+ ClearInfoBit(TTMATH_BIG_SIGN);
+ exponent.SetZero();
+
+ return true;
+ }
+ else
+ {
+ ClearInfoBit(TTMATH_BIG_ZERO);
+ }
+
+ return false;
+ }
+
+
+public:
+
+ /*!
+ this method clears a specific bit in the 'info' variable
+
+ bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
+ */
+ void ClearInfoBit(unsigned char bit)
+ {
+ info = info & (~bit);
+ }
+
+
+ /*!
+ this method sets a specific bit in the 'info' variable
+
+ bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
+
+ */
+ void SetInfoBit(unsigned char bit)
+ {
+ info = info | bit;
+ }
+
+
+ /*!
+ this method returns true if a specific bit in the 'info' variable is set
+
+ bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
+ */
+ bool IsInfoBit(unsigned char bit) const
+ {
+ return (info & bit) != 0;
+ }
+
+
+ /*!
+ this method sets zero
+ */
+ void SetZero()
+ {
+ info = TTMATH_BIG_ZERO;
+ exponent.SetZero();
+ mantissa.SetZero();
+
+ /*
+ we don't have to compensate zero
+ */
+ }
+
+
+ /*!
+ this method sets one
+ */
+ void SetOne()
+ {
+ info = 0;
+ mantissa.SetZero();
+ mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;
+ exponent = -sint(man * TTMATH_BITS_PER_UINT - 1);
+
+ // don't have to Standardize() - the last bit from mantissa is set
+ }
+
+
+ /*!
+ this method sets value 0.5
+ */
+ void Set05()
+ {
+ SetOne();
+ exponent.SubOne();
+ }
+
+
+ /*!
+ this method sets NaN flag (Not a Number)
+ when this flag is set that means there is no a valid number
+ */
+ void SetNan()
+ {
+ SetInfoBit(TTMATH_BIG_NAN);
+ }
+
+
+ /*!
+ this method sets NaN flag (Not a Number)
+ also clears the mantissa and exponent (similarly as it would be a zero value)
+ */
+ void SetZeroNan()
+ {
+ SetZero();
+ SetNan();
+ }
+
+
+ /*!
+ this method swappes this for an argument
+ */
+ void Swap(Big<exp, man> & ss2)
+ {
+ unsigned char info_temp = info;
+ info = ss2.info;
+ ss2.info = info_temp;
+
+ exponent.Swap(ss2.exponent);
+ mantissa.Swap(ss2.mantissa);
+ }
+
+
+private:
+
+ /*!
+ this method sets the mantissa of the value of pi
+ */
+ void SetMantissaPi()
+ {
+ // this is a static table which represents the value of Pi (mantissa of it)
+ // (first is the highest word)
+ // we must define this table as 'unsigned int' because
+ // both on 32bit and 64bit platforms this table is 32bit
+ static const unsigned int temp_table[] = {
+ 0xc90fdaa2, 0x2168c234, 0xc4c6628b, 0x80dc1cd1, 0x29024e08, 0x8a67cc74, 0x020bbea6, 0x3b139b22,
+ 0x514a0879, 0x8e3404dd, 0xef9519b3, 0xcd3a431b, 0x302b0a6d, 0xf25f1437, 0x4fe1356d, 0x6d51c245,
+ 0xe485b576, 0x625e7ec6, 0xf44c42e9, 0xa637ed6b, 0x0bff5cb6, 0xf406b7ed, 0xee386bfb, 0x5a899fa5,
+ 0xae9f2411, 0x7c4b1fe6, 0x49286651, 0xece45b3d, 0xc2007cb8, 0xa163bf05, 0x98da4836, 0x1c55d39a,
+ 0x69163fa8, 0xfd24cf5f, 0x83655d23, 0xdca3ad96, 0x1c62f356, 0x208552bb, 0x9ed52907, 0x7096966d,
+ 0x670c354e, 0x4abc9804, 0xf1746c08, 0xca18217c, 0x32905e46, 0x2e36ce3b, 0xe39e772c, 0x180e8603,
+ 0x9b2783a2, 0xec07a28f, 0xb5c55df0, 0x6f4c52c9, 0xde2bcbf6, 0x95581718, 0x3995497c, 0xea956ae5,
+ 0x15d22618, 0x98fa0510, 0x15728e5a, 0x8aaac42d, 0xad33170d, 0x04507a33, 0xa85521ab, 0xdf1cba64,
+ 0xecfb8504, 0x58dbef0a, 0x8aea7157, 0x5d060c7d, 0xb3970f85, 0xa6e1e4c7, 0xabf5ae8c, 0xdb0933d7,
+ 0x1e8c94e0, 0x4a25619d, 0xcee3d226, 0x1ad2ee6b, 0xf12ffa06, 0xd98a0864, 0xd8760273, 0x3ec86a64,
+ 0x521f2b18, 0x177b200c, 0xbbe11757, 0x7a615d6c, 0x770988c0, 0xbad946e2, 0x08e24fa0, 0x74e5ab31,
+ 0x43db5bfc, 0xe0fd108e, 0x4b82d120, 0xa9210801, 0x1a723c12, 0xa787e6d7, 0x88719a10, 0xbdba5b26,
+ 0x99c32718, 0x6af4e23c, 0x1a946834, 0xb6150bda, 0x2583e9ca, 0x2ad44ce8, 0xdbbbc2db, 0x04de8ef9,
+ 0x2e8efc14, 0x1fbecaa6, 0x287c5947, 0x4e6bc05d, 0x99b2964f, 0xa090c3a2, 0x233ba186, 0x515be7ed,
+ 0x1f612970, 0xcee2d7af, 0xb81bdd76, 0x2170481c, 0xd0069127, 0xd5b05aa9, 0x93b4ea98, 0x8d8fddc1,
+ 0x86ffb7dc, 0x90a6c08f, 0x4df435c9, 0x34028492, 0x36c3fab4, 0xd27c7026, 0xc1d4dcb2, 0x602646de,
+ 0xc9751e76, 0x3dba37bd, 0xf8ff9406, 0xad9e530e, 0xe5db382f, 0x413001ae, 0xb06a53ed, 0x9027d831,
+ 0x179727b0, 0x865a8918, 0xda3edbeb, 0xcf9b14ed, 0x44ce6cba, 0xced4bb1b, 0xdb7f1447, 0xe6cc254b,
+ 0x33205151, 0x2bd7af42, 0x6fb8f401, 0x378cd2bf, 0x5983ca01, 0xc64b92ec, 0xf032ea15, 0xd1721d03,
+ 0xf482d7ce, 0x6e74fef6, 0xd55e702f, 0x46980c82, 0xb5a84031, 0x900b1c9e, 0x59e7c97f, 0xbec7e8f3,
+ 0x23a97a7e, 0x36cc88be, 0x0f1d45b7, 0xff585ac5, 0x4bd407b2, 0x2b4154aa, 0xcc8f6d7e, 0xbf48e1d8,
+ 0x14cc5ed2, 0x0f8037e0, 0xa79715ee, 0xf29be328, 0x06a1d58b, 0xb7c5da76, 0xf550aa3d, 0x8a1fbff0,
+ 0xeb19ccb1, 0xa313d55c, 0xda56c9ec, 0x2ef29632, 0x387fe8d7, 0x6e3c0468, 0x043e8f66, 0x3f4860ee,
+ 0x12bf2d5b, 0x0b7474d6, 0xe694f91e, 0x6dbe1159, 0x74a3926f, 0x12fee5e4, 0x38777cb6, 0xa932df8c,
+ 0xd8bec4d0, 0x73b931ba, 0x3bc832b6, 0x8d9dd300, 0x741fa7bf, 0x8afc47ed, 0x2576f693, 0x6ba42466,
+ 0x3aab639c, 0x5ae4f568, 0x3423b474, 0x2bf1c978, 0x238f16cb, 0xe39d652d, 0xe3fdb8be, 0xfc848ad9,
+ 0x22222e04, 0xa4037c07, 0x13eb57a8, 0x1a23f0c7, 0x3473fc64, 0x6cea306b, 0x4bcbc886, 0x2f8385dd,
+ 0xfa9d4b7f, 0xa2c087e8, 0x79683303, 0xed5bdd3a, 0x062b3cf5, 0xb3a278a6, 0x6d2a13f8, 0x3f44f82d,
+ 0xdf310ee0, 0x74ab6a36, 0x4597e899, 0xa0255dc1, 0x64f31cc5, 0x0846851d, 0xf9ab4819, 0x5ded7ea1,
+ 0xb1d510bd, 0x7ee74d73, 0xfaf36bc3, 0x1ecfa268, 0x359046f4, 0xeb879f92, 0x4009438b, 0x481c6cd7,
+ 0x889a002e, 0xd5ee382b, 0xc9190da6, 0xfc026e47, 0x9558e447, 0x5677e9aa, 0x9e3050e2, 0x765694df,
+ 0xc81f56e8, 0x80b96e71, 0x60c980dd, 0x98a573ea, 0x4472065a, 0x139cd290, 0x6cd1cb72, 0x9ec52a53 // last one was: 0x9ec52a52
+ //0x86d44014, ...
+ // (the last word 0x9ec52a52 was rounded up because the next one is 0x86d44014 -- first bit is one 0x8..)
+ // 256 32bit words for the mantissa -- about 2464 valid decimal digits
+ };
+ // the value of PI is comming from the website http://zenwerx.com/pi.php
+ // 3101 digits were taken from this website
+ // (later the digits were compared with:
+ // http://www.eveandersson.com/pi/digits/1000000 and http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html )
+ // and they were set into Big<1,400> type (using operator=(const char*) on a 32bit platform)
+ // and then the first 256 words were taken into this table
+ // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
+ // and on 64bit platform value 128 (256/2=128))
+
+ mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
+ }
+
+public:
+
+
+ /*!
+ this method sets the value of pi
+ */
+ void SetPi()
+ {
+ SetMantissaPi();
+ info = 0;
+ exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
+ }
+
+
+ /*!
+ this method sets the value of 0.5 * pi
+ */
+ void Set05Pi()
+ {
+ SetMantissaPi();
+ info = 0;
+ exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 1;
+ }
+
+
+ /*!
+ this method sets the value of 2 * pi
+ */
+ void Set2Pi()
+ {
+ SetMantissaPi();
+ info = 0;
+ exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 3;
+ }
+
+
+ /*!
+ this method sets the value of e
+ (the base of the natural logarithm)
+ */
+ void SetE()
+ {
+ static const unsigned int temp_table[] = {
+ 0xadf85458, 0xa2bb4a9a, 0xafdc5620, 0x273d3cf1, 0xd8b9c583, 0xce2d3695, 0xa9e13641, 0x146433fb,
+ 0xcc939dce, 0x249b3ef9, 0x7d2fe363, 0x630c75d8, 0xf681b202, 0xaec4617a, 0xd3df1ed5, 0xd5fd6561,
+ 0x2433f51f, 0x5f066ed0, 0x85636555, 0x3ded1af3, 0xb557135e, 0x7f57c935, 0x984f0c70, 0xe0e68b77,
+ 0xe2a689da, 0xf3efe872, 0x1df158a1, 0x36ade735, 0x30acca4f, 0x483a797a, 0xbc0ab182, 0xb324fb61,
+ 0xd108a94b, 0xb2c8e3fb, 0xb96adab7, 0x60d7f468, 0x1d4f42a3, 0xde394df4, 0xae56ede7, 0x6372bb19,
+ 0x0b07a7c8, 0xee0a6d70, 0x9e02fce1, 0xcdf7e2ec, 0xc03404cd, 0x28342f61, 0x9172fe9c, 0xe98583ff,
+ 0x8e4f1232, 0xeef28183, 0xc3fe3b1b, 0x4c6fad73, 0x3bb5fcbc, 0x2ec22005, 0xc58ef183, 0x7d1683b2,
+ 0xc6f34a26, 0xc1b2effa, 0x886b4238, 0x611fcfdc, 0xde355b3b, 0x6519035b, 0xbc34f4de, 0xf99c0238,
+ 0x61b46fc9, 0xd6e6c907, 0x7ad91d26, 0x91f7f7ee, 0x598cb0fa, 0xc186d91c, 0xaefe1309, 0x85139270,
+ 0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x64f2e21e, 0x71f54bff, 0x5cae82ab, 0x9c9df69e,
+ 0xe86d2bc5, 0x22363a0d, 0xabc52197, 0x9b0deada, 0x1dbf9a42, 0xd5c4484e, 0x0abcd06b, 0xfa53ddef,
+ 0x3c1b20ee, 0x3fd59d7c, 0x25e41d2b, 0x669e1ef1, 0x6e6f52c3, 0x164df4fb, 0x7930e9e4, 0xe58857b6,
+ 0xac7d5f42, 0xd69f6d18, 0x7763cf1d, 0x55034004, 0x87f55ba5, 0x7e31cc7a, 0x7135c886, 0xefb4318a,
+ 0xed6a1e01, 0x2d9e6832, 0xa907600a, 0x918130c4, 0x6dc778f9, 0x71ad0038, 0x092999a3, 0x33cb8b7a,
+ 0x1a1db93d, 0x7140003c, 0x2a4ecea9, 0xf98d0acc, 0x0a8291cd, 0xcec97dcf, 0x8ec9b55a, 0x7f88a46b,
+ 0x4db5a851, 0xf44182e1, 0xc68a007e, 0x5e0dd902, 0x0bfd64b6, 0x45036c7a, 0x4e677d2c, 0x38532a3a,
+ 0x23ba4442, 0xcaf53ea6, 0x3bb45432, 0x9b7624c8, 0x917bdd64, 0xb1c0fd4c, 0xb38e8c33, 0x4c701c3a,
+ 0xcdad0657, 0xfccfec71, 0x9b1f5c3e, 0x4e46041f, 0x388147fb, 0x4cfdb477, 0xa52471f7, 0xa9a96910,
+ 0xb855322e, 0xdb6340d8, 0xa00ef092, 0x350511e3, 0x0abec1ff, 0xf9e3a26e, 0x7fb29f8c, 0x183023c3,
+ 0x587e38da, 0x0077d9b4, 0x763e4e4b, 0x94b2bbc1, 0x94c6651e, 0x77caf992, 0xeeaac023, 0x2a281bf6,
+ 0xb3a739c1, 0x22611682, 0x0ae8db58, 0x47a67cbe, 0xf9c9091b, 0x462d538c, 0xd72b0374, 0x6ae77f5e,
+ 0x62292c31, 0x1562a846, 0x505dc82d, 0xb854338a, 0xe49f5235, 0xc95b9117, 0x8ccf2dd5, 0xcacef403,
+ 0xec9d1810, 0xc6272b04, 0x5b3b71f9, 0xdc6b80d6, 0x3fdd4a8e, 0x9adb1e69, 0x62a69526, 0xd43161c1,
+ 0xa41d570d, 0x7938dad4, 0xa40e329c, 0xcff46aaa, 0x36ad004c, 0xf600c838, 0x1e425a31, 0xd951ae64,
+ 0xfdb23fce, 0xc9509d43, 0x687feb69, 0xedd1cc5e, 0x0b8cc3bd, 0xf64b10ef, 0x86b63142, 0xa3ab8829,
+ 0x555b2f74, 0x7c932665, 0xcb2c0f1c, 0xc01bd702, 0x29388839, 0xd2af05e4, 0x54504ac7, 0x8b758282,
+ 0x2846c0ba, 0x35c35f5c, 0x59160cc0, 0x46fd8251, 0x541fc68c, 0x9c86b022, 0xbb709987, 0x6a460e74,
+ 0x51a8a931, 0x09703fee, 0x1c217e6c, 0x3826e52c, 0x51aa691e, 0x0e423cfc, 0x99e9e316, 0x50c1217b,
+ 0x624816cd, 0xad9a95f9, 0xd5b80194, 0x88d9c0a0, 0xa1fe3075, 0xa577e231, 0x83f81d4a, 0x3f2fa457,
+ 0x1efc8ce0, 0xba8a4fe8, 0xb6855dfe, 0x72b0a66e, 0xded2fbab, 0xfbe58a30, 0xfafabe1c, 0x5d71a87e,
+ 0x2f741ef8, 0xc1fe86fe, 0xa6bbfde5, 0x30677f0d, 0x97d11d49, 0xf7a8443d, 0x0822e506, 0xa9f4614e,
+ 0x011e2a94, 0x838ff88c, 0xd68c8bb7, 0xc51eef6d, 0x49ea8ab4, 0xf2c3df5b, 0xb4e0735a, 0xb0d68749
+ // 0x2fe26dd4, ...
+ // 256 32bit words for the mantissa -- about 2464 valid decimal digits
+ };
+
+ // above value was calculated using Big<1,400> type on a 32bit platform
+ // and then the first 256 words were taken,
+ // the calculating was made by using ExpSurrounding0(1) method
+ // which took 1420 iterations
+ // (the result was compared with e taken from http://antwrp.gsfc.nasa.gov/htmltest/gifcity/e.2mil)
+ // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
+ // and on 64bit platform value 128 (256/2=128))
+
+ mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
+ exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
+ info = 0;
+ }
+
+
+ /*!
+ this method sets the value of ln(2)
+ the natural logarithm from 2
+ */
+ void SetLn2()
+ {
+ static const unsigned int temp_table[] = {
+ 0xb17217f7, 0xd1cf79ab, 0xc9e3b398, 0x03f2f6af, 0x40f34326, 0x7298b62d, 0x8a0d175b, 0x8baafa2b,
+ 0xe7b87620, 0x6debac98, 0x559552fb, 0x4afa1b10, 0xed2eae35, 0xc1382144, 0x27573b29, 0x1169b825,
+ 0x3e96ca16, 0x224ae8c5, 0x1acbda11, 0x317c387e, 0xb9ea9bc3, 0xb136603b, 0x256fa0ec, 0x7657f74b,
+ 0x72ce87b1, 0x9d6548ca, 0xf5dfa6bd, 0x38303248, 0x655fa187, 0x2f20e3a2, 0xda2d97c5, 0x0f3fd5c6,
+ 0x07f4ca11, 0xfb5bfb90, 0x610d30f8, 0x8fe551a2, 0xee569d6d, 0xfc1efa15, 0x7d2e23de, 0x1400b396,
+ 0x17460775, 0xdb8990e5, 0xc943e732, 0xb479cd33, 0xcccc4e65, 0x9393514c, 0x4c1a1e0b, 0xd1d6095d,
+ 0x25669b33, 0x3564a337, 0x6a9c7f8a, 0x5e148e82, 0x074db601, 0x5cfe7aa3, 0x0c480a54, 0x17350d2c,
+ 0x955d5179, 0xb1e17b9d, 0xae313cdb, 0x6c606cb1, 0x078f735d, 0x1b2db31b, 0x5f50b518, 0x5064c18b,
+ 0x4d162db3, 0xb365853d, 0x7598a195, 0x1ae273ee, 0x5570b6c6, 0x8f969834, 0x96d4e6d3, 0x30af889b,
+ 0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef9, 0x8d6f5177, 0xfbcf0755, 0x268a5c1f, 0x9538b982,
+ 0x61affd44, 0x6b1ca3cf, 0x5e9222b8, 0x8c66d3c5, 0x422183ed, 0xc9942109, 0x0bbb16fa, 0xf3d949f2,
+ 0x36e02b20, 0xcee886b9, 0x05c128d5, 0x3d0bd2f9, 0x62136319, 0x6af50302, 0x0060e499, 0x08391a0c,
+ 0x57339ba2, 0xbeba7d05, 0x2ac5b61c, 0xc4e9207c, 0xef2f0ce2, 0xd7373958, 0xd7622658, 0x901e646a,
+ 0x95184460, 0xdc4e7487, 0x156e0c29, 0x2413d5e3, 0x61c1696d, 0xd24aaebd, 0x473826fd, 0xa0c238b9,
+ 0x0ab111bb, 0xbd67c724, 0x972cd18b, 0xfbbd9d42, 0x6c472096, 0xe76115c0, 0x5f6f7ceb, 0xac9f45ae,
+ 0xcecb72f1, 0x9c38339d, 0x8f682625, 0x0dea891e, 0xf07afff3, 0xa892374e, 0x175eb4af, 0xc8daadd8,
+ 0x85db6ab0, 0x3a49bd0d, 0xc0b1b31d, 0x8a0e23fa, 0xc5e5767d, 0xf95884e0, 0x6425a415, 0x26fac51c,
+ 0x3ea8449f, 0xe8f70edd, 0x062b1a63, 0xa6c4c60c, 0x52ab3316, 0x1e238438, 0x897a39ce, 0x78b63c9f,
+ 0x364f5b8a, 0xef22ec2f, 0xee6e0850, 0xeca42d06, 0xfb0c75df, 0x5497e00c, 0x554b03d7, 0xd2874a00,
+ 0x0ca8f58d, 0x94f0341c, 0xbe2ec921, 0x56c9f949, 0xdb4a9316, 0xf281501e, 0x53daec3f, 0x64f1b783,
+ 0x154c6032, 0x0e2ff793, 0x33ce3573, 0xfacc5fdc, 0xf1178590, 0x3155bbd9, 0x0f023b22, 0x0224fcd8,
+ 0x471bf4f4, 0x45f0a88a, 0x14f0cd97, 0x6ea354bb, 0x20cdb5cc, 0xb3db2392, 0x88d58655, 0x4e2a0e8a,
+ 0x6fe51a8c, 0xfaa72ef2, 0xad8a43dc, 0x4212b210, 0xb779dfe4, 0x9d7307cc, 0x846532e4, 0xb9694eda,
+ 0xd162af05, 0x3b1751f3, 0xa3d091f6, 0x56658154, 0x12b5e8c2, 0x02461069, 0xac14b958, 0x784934b8,
+ 0xd6cce1da, 0xa5053701, 0x1aa4fb42, 0xb9a3def4, 0x1bda1f85, 0xef6fdbf2, 0xf2d89d2a, 0x4b183527,
+ 0x8fd94057, 0x89f45681, 0x2b552879, 0xa6168695, 0xc12963b0, 0xff01eaab, 0x73e5b5c1, 0x585318e7,
+ 0x624f14a5, 0x1a4a026b, 0x68082920, 0x57fd99b6, 0x6dc085a9, 0x8ac8d8ca, 0xf9eeeea9, 0x8a2400ca,
+ 0xc95f260f, 0xd10036f9, 0xf91096ac, 0x3195220a, 0x1a356b2a, 0x73b7eaad, 0xaf6d6058, 0x71ef7afb,
+ 0x80bc4234, 0x33562e94, 0xb12dfab4, 0x14451579, 0xdf59eae0, 0x51707062, 0x4012a829, 0x62c59cab,
+ 0x347f8304, 0xd889659e, 0x5a9139db, 0x14efcc30, 0x852be3e8, 0xfc99f14d, 0x1d822dd6, 0xe2f76797,
+ 0xe30219c8, 0xaa9ce884, 0x8a886eb3, 0xc87b7295, 0x988012e8, 0x314186ed, 0xbaf86856, 0xccd3c3b6,
+ 0xee94e62f, 0x110a6783, 0xd2aae89c, 0xcc3b76fc, 0x435a0ce1, 0x34c2838f, 0xd571ec6c, 0x1366a993 // last one was: 0x1366a992
+ //0xcbb9ac40, ...
+ // (the last word 0x1366a992 was rounded up because the next one is 0xcbb9ac40 -- first bit is one 0xc..)
+ // 256 32bit words for the mantissa -- about 2464 valid decimal digits
+ };
+
+ // above value was calculated using Big<1,400> type on a 32bit platform
+ // and then the first 256 words were taken,
+ // the calculating was made by using LnSurrounding1(2) method
+ // which took 4035 iterations
+ // (the result was compared with ln(2) taken from http://ja0hxv.calico.jp/pai/estart.html)
+ // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
+ // and on 64bit platform value 128 (256/2=128))
+
+ mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
+ exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT);
+ info = 0;
+ }
+
+
+ /*!
+ this method sets the value of ln(10)
+ the natural logarithm from 10
+
+ I introduced this constant especially to make the conversion ToString()
+ being faster. In fact the method ToString() is keeping values of logarithms
+ it has calculated but it must calculate the logarithm at least once.
+ If a program, which uses this library, is running for a long time this
+ would be ok, but for programs which are running shorter, for example for
+ CGI applications which only once are printing values, this would be much
+ inconvenience. Then if we're printing with base (radix) 10 and the mantissa
+ of our value is smaller than or equal to TTMATH_BUILTIN_VARIABLES_SIZE
+ we don't calculate the logarithm but take it from this constant.
+ */
+ void SetLn10()
+ {
+ static const unsigned int temp_table[] = {
+ 0x935d8ddd, 0xaaa8ac16, 0xea56d62b, 0x82d30a28, 0xe28fecf9, 0xda5df90e, 0x83c61e82, 0x01f02d72,
+ 0x962f02d7, 0xb1a8105c, 0xcc70cbc0, 0x2c5f0d68, 0x2c622418, 0x410be2da, 0xfb8f7884, 0x02e516d6,
+ 0x782cf8a2, 0x8a8c911e, 0x765aa6c3, 0xb0d831fb, 0xef66ceb0, 0x4ab3c6fa, 0x5161bb49, 0xd219c7bb,
+ 0xca67b35b, 0x23605085, 0x8e93368d, 0x44789c4f, 0x5b08b057, 0xd5ede20f, 0x469ea58e, 0x9305e981,
+ 0xe2478fca, 0xad3aee98, 0x9cd5b42e, 0x6a271619, 0xa47ecb26, 0x978c5d4f, 0xdb1d28ea, 0x57d4fdc0,
+ 0xe40bf3cc, 0x1e14126a, 0x45765cde, 0x268339db, 0xf47fa96d, 0xeb271060, 0xaf88486e, 0xa9b7401e,
+ 0x3dfd3c51, 0x748e6d6e, 0x3848c8d2, 0x5faf1bca, 0xe88047f1, 0x7b0d9b50, 0xa949eaaa, 0xdf69e8a5,
+ 0xf77e3760, 0x4e943960, 0xe38a5700, 0xffde2db1, 0xad6bfbff, 0xd821ba0a, 0x4cb0466d, 0x61ba648e,
+ 0xef99c8e5, 0xf6974f36, 0x3982a78c, 0xa45ddfc8, 0x09426178, 0x19127a6e, 0x3b70fcda, 0x2d732d47,
+ 0xb5e4b1c8, 0xc0e5a10a, 0xaa6604a5, 0x324ec3dc, 0xbc64ea80, 0x6e198566, 0x1f1d366c, 0x20663834,
+ 0x4d5e843f, 0x20642b97, 0x0a62d18e, 0x478f7bd5, 0x8fcd0832, 0x4a7b32a6, 0xdef85a05, 0xeb56323a,
+ 0x421ef5e0, 0xb00410a0, 0xa0d9c260, 0x794a976f, 0xf6ff363d, 0xb00b6b33, 0xf42c58de, 0xf8a3c52d,
+ 0xed69b13d, 0xc1a03730, 0xb6524dc1, 0x8c167e86, 0x99d6d20e, 0xa2defd2b, 0xd006f8b4, 0xbe145a2a,
+ 0xdf3ccbb3, 0x189da49d, 0xbc1261c8, 0xb3e4daad, 0x6a36cecc, 0xb2d5ae5b, 0x89bf752f, 0xb5dfb353,
+ 0xff3065c4, 0x0cfceec8, 0x1be5a9a9, 0x67fddc57, 0xc4b83301, 0x006bf062, 0x4b40ed7a, 0x56c6cdcd,
+ 0xa2d6fe91, 0x388e9e3e, 0x48a93f5f, 0x5e3b6eb4, 0xb81c4a5b, 0x53d49ea6, 0x8e668aea, 0xba83c7f8,
+ 0xfb5f06c3, 0x58ac8f70, 0xfa9d8c59, 0x8c574502, 0xbaf54c96, 0xc84911f0, 0x0482d095, 0x1a0af022,
+ 0xabbab080, 0xec97efd3, 0x671e4e0e, 0x52f166b6, 0xcd5cd226, 0x0dc67795, 0x2e1e34a3, 0xf799677f,
+ 0x2c1d48f1, 0x2944b6c5, 0x2ba1307e, 0x704d67f9, 0x1c1035e4, 0x4e927c63, 0x03cf12bf, 0xe2cd2e31,
+ 0xf8ee4843, 0x344d51b0, 0xf37da42b, 0x9f0b0fd9, 0x134fb2d9, 0xf815e490, 0xd966283f, 0x23962766,
+ 0xeceab1e4, 0xf3b5fc86, 0x468127e2, 0xb606d10d, 0x3a45f4b6, 0xb776102d, 0x2fdbb420, 0x80c8fa84,
+ 0xd0ff9f45, 0xc58aef38, 0xdb2410fd, 0x1f1cebad, 0x733b2281, 0x52ca5f36, 0xddf29daa, 0x544334b8,
+ 0xdeeaf659, 0x4e462713, 0x1ed485b4, 0x6a0822e1, 0x28db471c, 0xa53938a8, 0x44c3bef7, 0xf35215c8,
+ 0xb382bc4e, 0x3e4c6f15, 0x6285f54c, 0x17ab408e, 0xccbf7f5e, 0xd16ab3f6, 0xced2846d, 0xf457e14f,
+ 0xbb45d9c5, 0x646ad497, 0xac697494, 0x145de32e, 0x93907128, 0xd263d521, 0x79efb424, 0xd64651d6,
+ 0xebc0c9f0, 0xbb583a44, 0xc6412c84, 0x85bb29a6, 0x4d31a2cd, 0x92954469, 0xa32b1abd, 0xf7f5202c,
+ 0xa4aa6c93, 0x2e9b53cf, 0x385ab136, 0x2741f356, 0x5de9c065, 0x6009901c, 0x88abbdd8, 0x74efcf73,
+ 0x3f761ad4, 0x35f3c083, 0xfd6b8ee0, 0x0bef11c7, 0xc552a89d, 0x58ce4a21, 0xd71e54f2, 0x4157f6c7,
+ 0xd4622316, 0xe98956d7, 0x450027de, 0xcbd398d8, 0x4b98b36a, 0x0724c25c, 0xdb237760, 0xe9324b68,
+ 0x7523e506, 0x8edad933, 0x92197f00, 0xb853a326, 0xb330c444, 0x65129296, 0x34bc0670, 0xe177806d,
+ 0xe338dac4, 0x5537492a, 0xe19add83, 0xcf45000f, 0x5b423bce, 0x6497d209, 0xe30e18a1, 0x3cbf0687,
+ 0x67973103, 0xd9485366, 0x81506bba, 0x2e93a9a4, 0x7dd59d3f, 0xf17cd746, 0x8c2075be, 0x552a4348 // last one was: 0x552a4347
+ // 0xb4a638ef, ...
+ //(the last word 0x552a4347 was rounded up because the next one is 0xb4a638ef -- first bit is one 0xb..)
+ // 256 32bit words for the mantissa -- about 2464 valid digits (decimal)
+ };
+
+ // above value was calculated using Big<1,400> type on a 32bit platform
+ // and then the first 256 32bit words were taken,
+ // the calculating was made by using LnSurrounding1(10) method
+ // which took 22080 iterations
+ // (the result was compared with ln(10) taken from http://ja0hxv.calico.jp/pai/estart.html)
+ // (the formula used in LnSurrounding1(x) converges badly when
+ // the x is greater than one but in fact we can use it, only the
+ // number of iterations will be greater)
+ // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
+ // and on 64bit platform value 128 (256/2=128))
+
+ mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
+ exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
+ info = 0;
+ }
+
+
+ /*!
+ this method sets the maximum value which can be held in this type
+ */
+ void SetMax()
+ {
+ info = 0;
+ mantissa.SetMax();
+ exponent.SetMax();
+
+ // we don't have to use 'Standardizing()' because the last bit from
+ // the mantissa is set
+ }
+
+
+ /*!
+ this method sets the minimum value which can be held in this type
+ */
+ void SetMin()
+ {
+ info = 0;
+
+ mantissa.SetMax();
+ exponent.SetMax();
+ SetSign();
+
+ // we don't have to use 'Standardizing()' because the last bit from
+ // the mantissa is set
+ }
+
+
+ /*!
+ testing whether there is a value zero or not
+ */
+ bool IsZero() const
+ {
+ return IsInfoBit(TTMATH_BIG_ZERO);
+ }
+
+
+ /*!
+ this method returns true when there's the sign set
+ also we don't check the NaN flag
+ */
+ bool IsSign() const
+ {
+ return IsInfoBit(TTMATH_BIG_SIGN);
+ }
+
+
+ /*!
+ this method returns true when there is not a valid number
+ */
+ bool IsNan() const
+ {
+ return IsInfoBit(TTMATH_BIG_NAN);
+ }
+
+
+
+ /*!
+ this method clears the sign
+ (there'll be an absolute value)
+
+ e.g.
+ -1 -> 1
+ 2 -> 2
+ */
+ void Abs()
+ {
+ ClearInfoBit(TTMATH_BIG_SIGN);
+ }
+
+
+ /*!
+ this method remains the 'sign' of the value
+ e.g. -2 = -1
+ 0 = 0
+ 10 = 1
+ */
+ void Sgn()
+ {
+ // we have to check the NaN flag, because the next SetOne() method would clear it
+ if( IsNan() )
+ return;
+
+ if( IsSign() )
+ {
+ SetOne();
+ SetSign();
+ }
+ else
+ if( IsZero() )
+ SetZero(); // !! is nedeed here?
+ else
+ SetOne();
+ }
+
+
+
+ /*!
+ this method sets the sign
+
+ e.g.
+ -1 -> -1
+ 2 -> -2
+
+ we do not check whether there is a zero or not, if you're using this method
+ you must be sure that the value is (or will be afterwards) different from zero
+ */
+ void SetSign()
+ {
+ SetInfoBit(TTMATH_BIG_SIGN);
+ }
+
+
+ /*!
+ this method changes the sign
+ when there is a value of zero then the sign is not changed
+
+ e.g.
+ -1 -> 1
+ 2 -> -2
+ */
+ void ChangeSign()
+ {
+ // we don't have to check the NaN flag here
+
+ if( IsZero() )
+ return;
+
+ if( IsSign() )
+ ClearInfoBit(TTMATH_BIG_SIGN);
+ else
+ SetInfoBit(TTMATH_BIG_SIGN);
+ }
+
+
+
+private:
+
+ /*!
+ this method does the half-to-even rounding (banker's rounding)
+
+ if is_half is:
+ true - that means the rest was equal the half (0.5 decimal)
+ false - that means the rest was greater than a half (greater than 0.5 decimal)
+
+ if the rest was less than a half then don't call this method
+ (the rounding should does nothing then)
+ */
+ uint RoundHalfToEven(bool is_half, bool rounding_up = true)
+ {
+ uint c = 0;
+
+ if( !is_half || mantissa.IsTheLowestBitSet() )
+ {
+ if( rounding_up )
+ {
+ if( mantissa.AddOne() )
+ {
+ mantissa.Rcr(1, 1);
+ c = exponent.AddOne();
+ }
+ }
+ else
+ {
+ #ifdef TTMATH_DEBUG
+ uint c_from_zero =
+ #endif
+ mantissa.SubOne();
+
+ // we're using rounding_up=false in Add() when the mantissas have different signs
+ // mantissa can be zero only when previous mantissa was equal to ss2.mantissa
+ // but in such a case 'last_bit_set' will not be set and consequently 'do_rounding' will be false
+ TTMATH_ASSERT( c_from_zero == 0 )
+ }
+ }
+
+ return c;
+ }
+
+
+
+
+
+ /*!
+ *
+ * basic mathematic functions
+ *
+ */
+
+
+ /*!
+ this method adds one to the existing value
+ */
+ uint AddOne()
+ {
+ Big<exp, man> one;
+
+ one.SetOne();
+
+ return Add(one);
+ }
+
+
+ /*!
+ this method subtracts one from the existing value
+ */
+ uint SubOne()
+ {
+ Big<exp, man> one;
+
+ one.SetOne();
+
+ return Sub(one);
+ }
+
+
+private:
+
+
+ /*!
+ an auxiliary method for adding
+ */
+ void AddCheckExponents( Big<exp, man> & ss2,
+ Int<exp> & exp_offset,
+ bool & last_bit_set,
+ bool & rest_zero,
+ bool & do_adding,
+ bool & do_rounding)
+ {
+ Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
+
+ if( exp_offset == mantissa_size_in_bits )
+ {
+ last_bit_set = ss2.mantissa.IsTheHighestBitSet();
+ rest_zero = ss2.mantissa.AreFirstBitsZero(man*TTMATH_BITS_PER_UINT - 1);
+ do_rounding = true; // we'are only rounding
+ }
+ else
+ if( exp_offset < mantissa_size_in_bits )
+ {
+ uint moved = exp_offset.ToInt(); // how many times we must move ss2.mantissa
+ rest_zero = true;
+
+ if( moved > 0 )
+ {
+ last_bit_set = static_cast<bool>( ss2.mantissa.GetBit(moved-1) );
+
+ if( moved > 1 )
+ rest_zero = ss2.mantissa.AreFirstBitsZero(moved - 1);
+
+ // (2) moving 'exp_offset' times
+ ss2.mantissa.Rcr(moved, 0);
+ }
+
+ do_adding = true;
+ do_rounding = true;
+ }
+
+ // if exp_offset is greater than mantissa_size_in_bits then we do nothing
+ // ss2 is too small for taking into consideration in the sum
+ }
+
+
+ /*!
+ an auxiliary method for adding
+ */
+ uint AddMantissas( Big<exp, man> & ss2,
+ bool & last_bit_set,
+ bool & rest_zero)
+ {
+ uint c = 0;
+
+ if( IsSign() == ss2.IsSign() )
+ {
+ // values have the same signs
+ if( mantissa.Add(ss2.mantissa) )
+ {
+ // we have one bit more from addition (carry)
+ // now rest_zero means the old rest_zero with the old last_bit_set
+ rest_zero = (!last_bit_set && rest_zero);
+ last_bit_set = mantissa.Rcr(1,1);
+ c += exponent.AddOne();
+ }
+ }
+ else
+ {
+ // values have different signs
+ // there shouldn't be a carry here because
+ // (1) (2) guarantee that the mantissa of this
+ // is greater than or equal to the mantissa of the ss2
+
+ #ifdef TTMATH_DEBUG
+ uint c_temp =
+ #endif
+ mantissa.Sub(ss2.mantissa);
+
+ TTMATH_ASSERT( c_temp == 0 )
+ }
+
+ return c;
+ }
+
+
+public:
+
+
+ /*!
+ Addition this = this + ss2
+
+ it returns carry if the sum is too big
+ */
+ uint Add(Big<exp, man> ss2, bool round = true, bool adding = true)
+ {
+ bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
+ Int<exp> exp_offset( exponent );
+ uint c = 0;
+
+ if( IsNan() || ss2.IsNan() )
+ return CheckCarry(1);
+
+ if( !adding )
+ ss2.ChangeSign(); // subtracting
+
+ exp_offset.Sub( ss2.exponent );
+ exp_offset.Abs();
+
+ // (1) abs(this) will be >= abs(ss2)
+ if( SmallerWithoutSignThan(ss2) )
+ Swap(ss2);
+
+ if( ss2.IsZero() )
+ return 0;
+
+ last_bit_set = rest_zero = do_adding = do_rounding = false;
+ rounding_up = (IsSign() == ss2.IsSign());
+
+ AddCheckExponents(ss2, exp_offset, last_bit_set, rest_zero, do_adding, do_rounding);
+
+ if( do_adding )
+ c += AddMantissas(ss2, last_bit_set, rest_zero);
+
+ if( !round || !last_bit_set )
+ do_rounding = false;
+
+ if( do_rounding )
+ c += RoundHalfToEven(rest_zero, rounding_up);
+
+ if( do_adding || do_rounding )
+ c += Standardizing();
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ Subtraction this = this - ss2
+
+ it returns carry if the result is too big
+ */
+ uint Sub(const Big<exp, man> & ss2, bool round = true)
+ {
+ return Add(ss2, round, false);
+ }
+
+
+ /*!
+ bitwise AND
+
+ this and ss2 must be >= 0
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - this or ss2 was negative
+ */
+ uint BitAnd(Big<exp, man> ss2)
+ {
+ if( IsNan() || ss2.IsNan() )
+ return CheckCarry(1);
+
+ if( IsSign() || ss2.IsSign() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ if( IsZero() )
+ return 0;
+
+ if( ss2.IsZero() )
+ {
+ SetZero();
+ return 0;
+ }
+
+ Int<exp> exp_offset( exponent );
+ Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
+
+ uint c = 0;
+
+ exp_offset.Sub( ss2.exponent );
+ exp_offset.Abs();
+
+ // abs(this) will be >= abs(ss2)
+ if( SmallerWithoutSignThan(ss2) )
+ Swap(ss2);
+
+ if( exp_offset >= mantissa_size_in_bits )
+ {
+ // the second value is too small
+ SetZero();
+ return 0;
+ }
+
+ // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
+ ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
+ mantissa.BitAnd(ss2.mantissa);
+
+ c += Standardizing();
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ bitwise OR
+
+ this and ss2 must be >= 0
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - this or ss2 was negative
+ */
+ uint BitOr(Big<exp, man> ss2)
+ {
+ if( IsNan() || ss2.IsNan() )
+ return CheckCarry(1);
+
+ if( IsSign() || ss2.IsSign() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ if( IsZero() )
+ {
+ *this = ss2;
+ return 0;
+ }
+
+ if( ss2.IsZero() )
+ return 0;
+
+ Int<exp> exp_offset( exponent );
+ Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
+
+ uint c = 0;
+
+ exp_offset.Sub( ss2.exponent );
+ exp_offset.Abs();
+
+ // abs(this) will be >= abs(ss2)
+ if( SmallerWithoutSignThan(ss2) )
+ Swap(ss2);
+
+ if( exp_offset >= mantissa_size_in_bits )
+ // the second value is too small
+ return 0;
+
+ // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
+ ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
+ mantissa.BitOr(ss2.mantissa);
+
+ c += Standardizing();
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ bitwise XOR
+
+ this and ss2 must be >= 0
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - this or ss2 was negative
+ */
+ uint BitXor(Big<exp, man> ss2)
+ {
+ if( IsNan() || ss2.IsNan() )
+ return CheckCarry(1);
+
+ if( IsSign() || ss2.IsSign() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ if( ss2.IsZero() )
+ return 0;
+
+ if( IsZero() )
+ {
+ *this = ss2;
+ return 0;
+ }
+
+ Int<exp> exp_offset( exponent );
+ Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
+
+ uint c = 0;
+
+ exp_offset.Sub( ss2.exponent );
+ exp_offset.Abs();
+
+ // abs(this) will be >= abs(ss2)
+ if( SmallerWithoutSignThan(ss2) )
+ Swap(ss2);
+
+ if( exp_offset >= mantissa_size_in_bits )
+ // the second value is too small
+ return 0;
+
+ // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
+ ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
+ mantissa.BitXor(ss2.mantissa);
+
+ c += Standardizing();
+
+ return CheckCarry(c);
+ }
+
+
+
+ /*!
+ Multiplication this = this * ss2 (ss2 is uint)
+
+ ss2 without a sign
+ */
+ uint MulUInt(uint ss2)
+ {
+ UInt<man+1> man_result;
+ uint i,c = 0;
+
+ if( IsNan() )
+ return 1;
+
+ if( IsZero() )
+ return 0;
+
+ if( ss2 == 0 )
+ {
+ SetZero();
+ return 0;
+ }
+
+ // man_result = mantissa * ss2.mantissa
+ mantissa.MulInt(ss2, man_result);
+
+ sint bit = UInt<man>::FindLeadingBitInWord(man_result.table[man]); // man - last word
+
+ if( bit!=-1 && uint(bit) > (TTMATH_BITS_PER_UINT/2) )
+ {
+ // 'i' will be from 0 to TTMATH_BITS_PER_UINT
+ i = man_result.CompensationToLeft();
+ c = exponent.Add( TTMATH_BITS_PER_UINT - i );
+
+ for(i=0 ; i<man ; ++i)
+ mantissa.table[i] = man_result.table[i+1];
+ }
+ else
+ {
+ if( bit != -1 )
+ {
+ man_result.Rcr(bit+1, 0);
+ c += exponent.Add(bit+1);
+ }
+
+ for(i=0 ; i<man ; ++i)
+ mantissa.table[i] = man_result.table[i];
+ }
+
+ c += Standardizing();
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ Multiplication this = this * ss2 (ss2 is sint)
+
+ ss2 with a sign
+ */
+ uint MulInt(sint ss2)
+ {
+ if( IsNan() )
+ return 1;
+
+ if( ss2 == 0 )
+ {
+ SetZero();
+ return 0;
+ }
+
+ if( IsZero() )
+ return 0;
+
+ if( IsSign() == (ss2<0) )
+ {
+ // the signs are the same (both are either - or +), the result is positive
+ Abs();
+ }
+ else
+ {
+ // the signs are different, the result is negative
+ SetSign();
+ }
+
+ if( ss2<0 )
+ ss2 = -ss2;
+
+
+ return MulUInt( uint(ss2) );
+ }
+
+
+private:
+
+
+ /*!
+ this method checks whether a table pointed by 'tab' and 'len'
+ has the value 0.5 decimal
+ (it is treated as the comma operator would be before the highest bit)
+ call this method only if the highest bit is set - you have to test it beforehand
+
+ return:
+ true - tab was equal the half (0.5 decimal)
+ false - tab was greater than a half (greater than 0.5 decimal)
+
+ */
+ bool CheckGreaterOrEqualHalf(uint * tab, uint len)
+ {
+ uint i;
+
+ TTMATH_ASSERT( len>0 && (tab[len-1] & TTMATH_UINT_HIGHEST_BIT)!=0 )
+
+ for(i=0 ; i<len-1 ; ++i)
+ if( tab[i] != 0 )
+ return false;
+
+ if( tab[i] != TTMATH_UINT_HIGHEST_BIT )
+ return false;
+
+ return true;
+ }
+
+
+private:
+
+ /*!
+ multiplication this = this * ss2
+ this method returns a carry
+ */
+ uint MulRef(const Big<exp, man> & ss2, bool round = true)
+ {
+ TTMATH_REFERENCE_ASSERT( ss2 )
+
+ UInt<man*2> man_result;
+ uint c = 0;
+ uint i;
+
+ if( IsNan() || ss2.IsNan() )
+ return CheckCarry(1);
+
+ if( IsZero() )
+ return 0;
+
+ if( ss2.IsZero() )
+ {
+ SetZero();
+ return 0;
+ }
+
+ // man_result = mantissa * ss2.mantissa
+ mantissa.MulBig(ss2.mantissa, man_result);
+
+ // 'i' will be from 0 to man*TTMATH_BITS_PER_UINT
+ // because mantissa and ss2.mantissa are standardized
+ // (the highest bit in man_result is set to 1 or
+ // if there is a zero value in man_result the method CompensationToLeft()
+ // returns 0 but we'll correct this at the end in Standardizing() method)
+ i = man_result.CompensationToLeft();
+ uint exp_add = man * TTMATH_BITS_PER_UINT - i;
+
+ if( exp_add )
+ c += exponent.Add( exp_add );
+
+ c += exponent.Add( ss2.exponent );
+
+ for(i=0 ; i<man ; ++i)
+ mantissa.table[i] = man_result.table[i+man];
+
+ if( round && (man_result.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+ {
+ bool is_half = CheckGreaterOrEqualHalf(man_result.table, man);
+ c += RoundHalfToEven(is_half);
+ }
+
+ if( IsSign() == ss2.IsSign() )
+ {
+ // the signs are the same, the result is positive
+ Abs();
+ }
+ else
+ {
+ // the signs are different, the result is negative
+ // if the value is zero it will be corrected later in Standardizing method
+ SetSign();
+ }
+
+ c += Standardizing();
+
+ return CheckCarry(c);
+ }
+
+
+public:
+
+
+ /*!
+ multiplication this = this * ss2
+ this method returns a carry
+ */
+ uint Mul(const Big<exp, man> & ss2, bool round = true)
+ {
+ if( this == &ss2 )
+ {
+ Big<exp, man> copy_ss2(ss2);
+ return MulRef(copy_ss2, round);
+ }
+ else
+ {
+ return MulRef(ss2, round);
+ }
+ }
+
+
+private:
+
+ /*!
+ division this = this / ss2
+
+ return value:
+ 0 - ok
+ 1 - carry (in a division carry can be as well)
+ 2 - improper argument (ss2 is zero)
+ */
+ uint DivRef(const Big<exp, man> & ss2, bool round = true)
+ {
+ TTMATH_REFERENCE_ASSERT( ss2 )
+
+ UInt<man*2> man1;
+ UInt<man*2> man2;
+ uint i,c = 0;
+
+ if( IsNan() || ss2.IsNan() )
+ return CheckCarry(1);
+
+ if( ss2.IsZero() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ if( IsZero() )
+ return 0;
+
+ // !! this two loops can be joined together
+
+ for(i=0 ; i<man ; ++i)
+ {
+ man1.table[i+man] = mantissa.table[i];
+ man2.table[i] = ss2.mantissa.table[i];
+ }
+
+ for(i=0 ; i<man ; ++i)
+ {
+ man1.table[i] = 0;
+ man2.table[i+man] = 0;
+ }
+
+ man1.Div(man2);
+
+ i = man1.CompensationToLeft();
+
+ if( i )
+ c += exponent.Sub(i);
+
+ c += exponent.Sub(ss2.exponent);
+
+ for(i=0 ; i<man ; ++i)
+ mantissa.table[i] = man1.table[i+man];
+
+ if( round && (man1.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+ {
+ bool is_half = CheckGreaterOrEqualHalf(man1.table, man);
+ c += RoundHalfToEven(is_half);
+ }
+
+ if( IsSign() == ss2.IsSign() )
+ Abs();
+ else
+ SetSign(); // if there is a zero it will be corrected in Standardizing()
+
+ c += Standardizing();
+
+ return CheckCarry(c);
+ }
+
+
+public:
+
+ /*!
+ division this = this / ss2
+
+ return value:
+ 0 - ok
+ 1 - carry (in a division carry can be as well)
+ 2 - improper argument (ss2 is zero)
+ */
+ uint Div(const Big<exp, man> & ss2, bool round = true)
+ {
+ if( this == &ss2 )
+ {
+ Big<exp, man> copy_ss2(ss2);
+ return DivRef(copy_ss2, round);
+ }
+ else
+ {
+ return DivRef(ss2, round);
+ }
+ }
+
+
+private:
+
+ /*!
+ the remainder from a division
+ */
+ uint ModRef(const Big<exp, man> & ss2)
+ {
+ TTMATH_REFERENCE_ASSERT( ss2 )
+
+ uint c = 0;
+
+ if( IsNan() || ss2.IsNan() )
+ return CheckCarry(1);
+
+ if( ss2.IsZero() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ if( !SmallerWithoutSignThan(ss2) )
+ {
+ Big<exp, man> temp(*this);
+
+ c = temp.Div(ss2);
+ temp.SkipFraction();
+ c += temp.Mul(ss2);
+ c += Sub(temp);
+
+ if( !SmallerWithoutSignThan( ss2 ) )
+ c += 1;
+ }
+
+ return CheckCarry(c);
+ }
+
+
+public:
+
+ /*!
+ the remainder from a division
+
+ e.g.
+ 12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6
+ -12.6 mod 3 = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
+ 12.6 mod -3 = 0.6
+ -12.6 mod -3 = -0.6
+
+ it means:
+ in other words: this(old) = ss2 * q + this(new)
+
+ return value:
+ 0 - ok
+ 1 - carry
+ 2 - improper argument (ss2 is zero)
+ */
+ uint Mod(const Big<exp, man> & ss2)
+ {
+ if( this == &ss2 )
+ {
+ Big<exp, man> copy_ss2(ss2);
+ return ModRef(copy_ss2);
+ }
+ else
+ {
+ return ModRef(ss2);
+ }
+ }
+
+
+ /*!
+ this method returns: 'this' mod 2
+ (either zero or one)
+
+ this method is much faster than using Mod( object_with_value_two )
+ */
+ uint Mod2() const
+ {
+ if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) )
+ return 0;
+
+ sint exp_int = exponent.ToInt();
+ // 'exp_int' is negative (or zero), we set it as positive
+ exp_int = -exp_int;
+
+ return mantissa.GetBit(exp_int);
+ }
+
+
+ /*!
+ power this = this ^ pow
+ (pow without a sign)
+
+ binary algorithm (r-to-l)
+
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - incorrect arguments (0^0)
+ */
+ template<uint pow_size>
+ uint Pow(UInt<pow_size> pow)
+ {
+ if( IsNan() )
+ return 1;
+
+ if( IsZero() )
+ {
+ if( pow.IsZero() )
+ {
+ // we don't define zero^zero
+ SetNan();
+ return 2;
+ }
+
+ // 0^(+something) is zero
+ return 0;
+ }
+
+ Big<exp, man> start(*this);
+ Big<exp, man> result;
+ result.SetOne();
+ uint c = 0;
+
+ while( !c )
+ {
+ if( pow.table[0] & 1 )
+ c += result.Mul(start);
+
+ pow.Rcr(1);
+
+ if( pow.IsZero() )
+ break;
+
+ c += start.Mul(start);
+ }
+
+ *this = result;
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ power this = this ^ pow
+ p can be negative
+
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - incorrect arguments 0^0 or 0^(-something)
+ */
+ template<uint pow_size>
+ uint Pow(Int<pow_size> pow)
+ {
+ if( IsNan() )
+ return 1;
+
+ if( !pow.IsSign() )
+ return Pow( UInt<pow_size>(pow) );
+
+ if( IsZero() )
+ {
+ // if 'p' is negative then
+ // 'this' must be different from zero
+ SetNan();
+ return 2;
+ }
+
+ uint c = pow.ChangeSign();
+
+ Big<exp, man> t(*this);
+ c += t.Pow( UInt<pow_size>(pow) ); // here can only be a carry (return:1)
+
+ SetOne();
+ c += Div(t);
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ power this = this ^ abs([pow])
+ pow is treated as a value without a sign and without a fraction
+ if pow has a sign then the method pow.Abs() is used
+ if pow has a fraction the fraction is skipped (not used in calculation)
+
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - incorrect arguments (0^0)
+ */
+ uint PowUInt(Big<exp, man> pow)
+ {
+ if( IsNan() || pow.IsNan() )
+ return CheckCarry(1);
+
+ if( IsZero() )
+ {
+ if( pow.IsZero() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ // 0^(+something) is zero
+ return 0;
+ }
+
+ if( pow.IsSign() )
+ pow.Abs();
+
+ Big<exp, man> start(*this);
+ Big<exp, man> result;
+ Big<exp, man> one;
+ uint c = 0;
+ one.SetOne();
+ result = one;
+
+ while( !c )
+ {
+ if( pow.Mod2() )
+ c += result.Mul(start);
+
+ c += pow.exponent.SubOne();
+
+ if( pow < one )
+ break;
+
+ c += start.Mul(start);
+ }
+
+ *this = result;
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ power this = this ^ [pow]
+ pow is treated as a value without a fraction
+ pow can be negative
+
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - incorrect arguments 0^0 or 0^(-something)
+ */
+ uint PowInt(const Big<exp, man> & pow)
+ {
+ if( IsNan() || pow.IsNan() )
+ return CheckCarry(1);
+
+ if( !pow.IsSign() )
+ return PowUInt(pow);
+
+ if( IsZero() )
+ {
+ // if 'pow' is negative then
+ // 'this' must be different from zero
+ SetNan();
+ return 2;
+ }
+
+ Big<exp, man> temp(*this);
+ uint c = temp.PowUInt(pow); // here can only be a carry (result:1)
+
+ SetOne();
+ c += Div(temp);
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ power this = this ^ pow
+ this must be greater than zero (this > 0)
+ pow can be negative and with fraction
+
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - incorrect argument ('this' <= 0)
+ */
+ uint PowFrac(const Big<exp, man> & pow)
+ {
+ if( IsNan() || pow.IsNan() )
+ return CheckCarry(1);
+
+ Big<exp, man> temp;
+ uint c = temp.Ln(*this);
+
+ if( c != 0 ) // can be 2 from Ln()
+ {
+ SetNan();
+ return c;
+ }
+
+ c += temp.Mul(pow);
+ c += Exp(temp);
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ power this = this ^ pow
+ pow can be negative and with fraction
+
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - incorrect argument ('this' or 'pow')
+ */
+ uint Pow(const Big<exp, man> & pow)
+ {
+ if( IsNan() || pow.IsNan() )
+ return CheckCarry(1);
+
+ if( IsZero() )
+ {
+ // 0^pow will be 0 only for pow>0
+ if( pow.IsSign() || pow.IsZero() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ SetZero();
+
+ return 0;
+ }
+
+ if( pow.exponent>-sint(man*TTMATH_BITS_PER_UINT) && pow.exponent<=0 )
+ {
+ if( pow.IsInteger() )
+ return PowInt( pow );
+ }
+
+ return PowFrac(pow);
+ }
+
+
+ /*!
+ this function calculates the square root
+ e.g. let this=9 then this.Sqrt() gives 3
+
+ return: 0 - ok
+ 1 - carry
+ 2 - improper argument (this<0 or NaN)
+ */
+ uint Sqrt()
+ {
+ if( IsNan() || IsSign() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ if( IsZero() )
+ return 0;
+
+ Big<exp, man> old(*this);
+ Big<exp, man> ln;
+ uint c = 0;
+
+ // we're using the formula: sqrt(x) = e ^ (ln(x) / 2)
+ c += ln.Ln(*this);
+ c += ln.exponent.SubOne(); // ln = ln / 2
+ c += Exp(ln);
+
+ // above formula doesn't give accurate results for some integers
+ // e.g. Sqrt(81) would not be 9 but a value very closed to 9
+ // we're rounding the result, calculating result*result and comparing
+ // with the old value, if they are equal then the result is an integer too
+
+ if( !c && old.IsInteger() && !IsInteger() )
+ {
+ Big<exp, man> temp(*this);
+ c += temp.Round();
+
+ Big<exp, man> temp2(temp);
+ c += temp.Mul(temp2);
+
+ if( temp == old )
+ *this = temp2;
+ }
+
+ return CheckCarry(c);
+ }
+
+
+private:
+
+#ifdef TTMATH_CONSTANTSGENERATOR
+public:
+#endif
+
+ /*!
+ Exponent this = exp(x) = e^x where x is in (-1,1)
+
+ we're using the formula exp(x) = 1 + (x)/(1!) + (x^2)/(2!) + (x^3)/(3!) + ...
+ */
+ void ExpSurrounding0(const Big<exp,man> & x, uint * steps = 0)
+ {
+ TTMATH_REFERENCE_ASSERT( x )
+
+ Big<exp,man> denominator, denominator_i;
+ Big<exp,man> one, old_value, next_part;
+ Big<exp,man> numerator = x;
+
+ SetOne();
+ one.SetOne();
+ denominator.SetOne();
+ denominator_i.SetOne();
+
+ uint i;
+ old_value = *this;
+
+ // we begin from 1 in order to not test at the beginning
+ #ifdef TTMATH_CONSTANTSGENERATOR
+ for(i=1 ; true ; ++i)
+ #else
+ for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+ #endif
+ {
+ bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
+
+ next_part = numerator;
+
+ if( next_part.Div( denominator ) )
+ // if there is a carry here we only break the loop
+ // however the result we return as good
+ // it means there are too many parts of the formula
+ break;
+
+ // there shouldn't be a carry here
+ Add( next_part );
+
+ if( testing )
+ {
+ if( old_value == *this )
+ // we've added next few parts of the formula but the result
+ // is still the same then we break the loop
+ break;
+ else
+ old_value = *this;
+ }
+
+ // we set the denominator and the numerator for a next part of the formula
+ if( denominator_i.Add(one) )
+ // if there is a carry here the result we return as good
+ break;
+
+ if( denominator.Mul(denominator_i) )
+ break;
+
+ if( numerator.Mul(x) )
+ break;
+ }
+
+ if( steps )
+ *steps = i;
+ }
+
+public:
+
+
+ /*!
+ Exponent this = exp(x) = e^x
+
+ we're using the fact that our value is stored in form of:
+ x = mantissa * 2^exponent
+ then
+ e^x = e^(mantissa* 2^exponent) or
+ e^x = (e^mantissa)^(2^exponent)
+
+ 'Exp' returns a carry if we can't count the result ('x' is too big)
+ */
+ uint Exp(const Big<exp,man> & x)
+ {
+ uint c = 0;
+
+ if( x.IsNan() )
+ return CheckCarry(1);
+
+ if( x.IsZero() )
+ {
+ SetOne();
+ return 0;
+ }
+
+ // m will be the value of the mantissa in range (-1,1)
+ Big<exp,man> m(x);
+ m.exponent = -sint(man*TTMATH_BITS_PER_UINT);
+
+ // 'e_' will be the value of '2^exponent'
+ // e_.mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT; and
+ // e_.exponent.Add(1) mean:
+ // e_.mantissa.table[0] = 1;
+ // e_.Standardizing();
+ // e_.exponent.Add(man*TTMATH_BITS_PER_UINT)
+ // (we must add 'man*TTMATH_BITS_PER_UINT' because we've taken it from the mantissa)
+ Big<exp,man> e_(x);
+ e_.mantissa.SetZero();
+ e_.mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;
+ c += e_.exponent.Add(1);
+ e_.Abs();
+
+ /*
+ now we've got:
+ m - the value of the mantissa in range (-1,1)
+ e_ - 2^exponent
+
+ e_ can be as:
+ ...2^-2, 2^-1, 2^0, 2^1, 2^2 ...
+ ...1/4 , 1/2 , 1 , 2 , 4 ...
+
+ above one e_ is integer
+
+ if e_ is greater than 1 we calculate the exponent as:
+ e^(m * e_) = ExpSurrounding0(m) ^ e_
+ and if e_ is smaller or equal one we calculate the exponent in this way:
+ e^(m * e_) = ExpSurrounding0(m* e_)
+ because if e_ is smaller or equal 1 then the product of m*e_ is smaller or equal m
+ */
+
+ if( e_ <= 1 )
+ {
+ m.Mul(e_);
+ ExpSurrounding0(m);
+ }
+ else
+ {
+ ExpSurrounding0(m);
+ c += PowUInt(e_);
+ }
+
+ return CheckCarry(c);
+ }
+
+
+
+
+private:
+
+#ifdef TTMATH_CONSTANTSGENERATOR
+public:
+#endif
+
+ /*!
+ Natural logarithm this = ln(x) where x in range <1,2)
+
+ we're using the formula:
+ ln x = 2 * [ (x-1)/(x+1) + (1/3)((x-1)/(x+1))^3 + (1/5)((x-1)/(x+1))^5 + ... ]
+ */
+ void LnSurrounding1(const Big<exp,man> & x, uint * steps = 0)
+ {
+ Big<exp,man> old_value, next_part, denominator, one, two, x1(x), x2(x);
+
+ one.SetOne();
+
+ if( x == one )
+ {
+ // LnSurrounding1(1) is 0
+ SetZero();
+ return;
+ }
+
+ two = 2;
+
+ x1.Sub(one);
+ x2.Add(one);
+
+ x1.Div(x2);
+ x2 = x1;
+ x2.Mul(x1);
+
+ denominator.SetOne();
+ SetZero();
+
+ old_value = *this;
+ uint i;
+
+
+ #ifdef TTMATH_CONSTANTSGENERATOR
+ for(i=1 ; true ; ++i)
+ #else
+ // we begin from 1 in order to not test at the beginning
+ for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+ #endif
+ {
+ bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
+
+ next_part = x1;
+
+ if( next_part.Div(denominator) )
+ // if there is a carry here we only break the loop
+ // however the result we return as good
+ // it means there are too many parts of the formula
+ break;
+
+ // there shouldn't be a carry here
+ Add(next_part);
+
+ if( testing )
+ {
+ if( old_value == *this )
+ // we've added next (step_test) parts of the formula but the result
+ // is still the same then we break the loop
+ break;
+ else
+ old_value = *this;
+ }
+
+ if( x1.Mul(x2) )
+ // if there is a carry here the result we return as good
+ break;
+
+ if( denominator.Add(two) )
+ break;
+ }
+
+ // this = this * 2
+ // ( there can't be a carry here because we calculate the logarithm between <1,2) )
+ exponent.AddOne();
+
+ if( steps )
+ *steps = i;
+ }
+
+
+
+
+public:
+
+
+ /*!
+ Natural logarithm this = ln(x)
+ (a logarithm with the base equal 'e')
+
+ we're using the fact that our value is stored in form of:
+ x = mantissa * 2^exponent
+ then
+ ln(x) = ln (mantissa * 2^exponent) = ln (mantissa) + (exponent * ln (2))
+
+ the mantissa we'll show as a value from range <1,2) because the logarithm
+ is decreasing too fast when 'x' is going to 0
+
+ return values:
+ 0 - ok
+ 1 - overflow (carry)
+ 2 - incorrect argument (x<=0)
+ */
+ uint Ln(const Big<exp,man> & x)
+ {
+ if( x.IsNan() )
+ return CheckCarry(1);
+
+ if( x.IsSign() || x.IsZero() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ Big<exp,man> exponent_temp;
+ exponent_temp.FromInt( x.exponent );
+
+ // m will be the value of the mantissa in range <1,2)
+ Big<exp,man> m(x);
+ m.exponent = -sint(man*TTMATH_BITS_PER_UINT - 1);
+
+ // we must add 'man*TTMATH_BITS_PER_UINT-1' because we've taken it from the mantissa
+ uint c = exponent_temp.Add(man*TTMATH_BITS_PER_UINT-1);
+
+ LnSurrounding1(m);
+
+ Big<exp,man> ln2;
+ ln2.SetLn2();
+ c += exponent_temp.Mul(ln2);
+ c += Add(exponent_temp);
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ Logarithm from 'x' with a 'base'
+
+ we're using the formula:
+ Log(x) with 'base' = ln(x) / ln(base)
+
+ return values:
+ 0 - ok
+ 1 - overflow
+ 2 - incorrect argument (x<=0)
+ 3 - incorrect base (a<=0 lub a=1)
+ */
+ uint Log(const Big<exp,man> & x, const Big<exp,man> & base)
+ {
+ if( x.IsNan() || base.IsNan() )
+ return CheckCarry(1);
+
+ if( x.IsSign() || x.IsZero() )
+ {
+ SetNan();
+ return 2;
+ }
+
+ Big<exp,man> denominator;;
+ denominator.SetOne();
+
+ if( base.IsSign() || base.IsZero() || base==denominator )
+ {
+ SetNan();
+ return 3;
+ }
+
+ if( x == denominator ) // (this is: if x == 1)
+ {
+ // log(1) is 0
+ SetZero();
+ return 0;
+ }
+
+ // another error values we've tested at the beginning
+ // there can only be a carry
+ uint c = Ln(x);
+
+ c += denominator.Ln(base);
+ c += Div(denominator);
+
+ return CheckCarry(c);
+ }
+
+
+
+
+ /*!
+ *
+ * converting methods
+ *
+ */
+
+
+ /*!
+ converting from another type of a Big object
+ */
+ template<uint another_exp, uint another_man>
+ uint FromBig(const Big<another_exp, another_man> & another)
+ {
+ info = another.info;
+
+ if( IsNan() )
+ return 1;
+
+ if( exponent.FromInt(another.exponent) )
+ {
+ SetNan();
+ return 1;
+ }
+
+ uint man_len_min = (man < another_man)? man : another_man;
+ uint i;
+ uint c = 0;
+
+ for( i = 0 ; i<man_len_min ; ++i )
+ mantissa.table[man-1-i] = another.mantissa.table[another_man-1-i];
+
+ for( ; i<man ; ++i )
+ mantissa.table[man-1-i] = 0;
+
+
+ // MS Visual Express 2005 reports a warning (in the lines with 'uint man_diff = ...'):
+ // warning C4307: '*' : integral constant overflow
+ // but we're using 'if( man > another_man )' and 'if( man < another_man )' and there'll be no such situation here
+ #ifdef _MSC_VER
+ #pragma warning( disable: 4307 )
+ #endif
+
+ if( man > another_man )
+ {
+ uint man_diff = (man - another_man) * TTMATH_BITS_PER_UINT;
+ c += exponent.SubInt(man_diff, 0);
+ }
+ else
+ if( man < another_man )
+ {
+ uint man_diff = (another_man - man) * TTMATH_BITS_PER_UINT;
+ c += exponent.AddInt(man_diff, 0);
+ }
+
+ #ifdef _MSC_VER
+ #pragma warning( default: 4307 )
+ #endif
+
+ // mantissa doesn't have to be standardized (either the highest bit is set or all bits are equal zero)
+ CorrectZero();
+
+ return CheckCarry(c);
+ }
+
+
+private:
+
+ /*!
+ an auxiliary method for converting 'this' into 'result'
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToUIntOrInt(uint & result) const
+ {
+ result = 0;
+
+ if( IsZero() )
+ return 0;
+
+ sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
+
+ if( exponent > maxbit + sint(TTMATH_BITS_PER_UINT) )
+ // if exponent > (maxbit + sint(TTMATH_BITS_PER_UINT)) the value can't be passed
+ // into the 'sint' type (it's too big)
+ return 1;
+
+ if( exponent <= maxbit )
+ // our value is from the range of (-1,1) and we return zero
+ return 0;
+
+ // exponent is from a range of (maxbit, maxbit + sint(TTMATH_BITS_PER_UINT) >
+ // and [maxbit + sint(TTMATH_BITS_PER_UINT] <= 0
+ sint how_many_bits = exponent.ToInt();
+
+ // how_many_bits is negative, we'll make it positive
+ how_many_bits = -how_many_bits;
+
+ result = (mantissa.table[man-1] >> (how_many_bits % TTMATH_BITS_PER_UINT));
+
+ return 0;
+ }
+
+
+public:
+
+ /*!
+ this method converts 'this' into uint
+ */
+ uint ToUInt() const
+ {
+ uint result;
+
+ ToUInt(result);
+
+ return result;
+ }
+
+
+ /*!
+ this method converts 'this' into 'result'
+
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToUInt(uint & result) const
+ {
+ if( ToUIntOrInt(result) )
+ return 1;
+
+ if( IsSign() )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts 'this' into sint
+ */
+ sint ToInt() const
+ {
+ sint result;
+
+ ToInt(result);
+
+ return result;
+ }
+
+
+ /*!
+ this method converts 'this' into 'result'
+
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToInt(uint & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts 'this' into 'result'
+
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToInt(sint & result) const
+ {
+ uint result_uint;
+
+ uint c = ToUIntOrInt(result_uint);
+ result = sint(result_uint);
+
+ if( c )
+ return 1;
+
+ uint mask = 0;
+
+ if( IsSign() )
+ {
+ mask = TTMATH_UINT_MAX_VALUE;
+ result = -result;
+ }
+
+ return ((result & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
+ }
+
+
+private:
+
+ /*!
+ an auxiliary method for converting 'this' into 'result'
+
+ if the value is too big this method returns a carry (1)
+ */
+ template<uint int_size>
+ uint ToUIntOrInt(UInt<int_size> & result) const
+ {
+ result.SetZero();
+
+ if( IsZero() )
+ return 0;
+
+ sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
+
+ if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )
+ // if exponent > (maxbit + sint(int_size*TTMATH_BITS_PER_UINT)) the value can't be passed
+ // into the 'UInt<int_size>' type (it's too big)
+ return 1;
+
+ if( exponent <= maxbit )
+ // our value is from range (-1,1) and we return zero
+ return 0;
+
+ sint how_many_bits = exponent.ToInt();
+
+ if( how_many_bits < 0 )
+ {
+ how_many_bits = -how_many_bits;
+ uint index = how_many_bits / TTMATH_BITS_PER_UINT;
+
+ UInt<man> mantissa_temp(mantissa);
+ mantissa_temp.Rcr( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
+
+ for(uint i=index, a=0 ; i<man ; ++i,++a)
+ result.table[a] = mantissa_temp.table[i];
+ }
+ else
+ {
+ uint index = how_many_bits / TTMATH_BITS_PER_UINT;
+
+ if( index + (man-1) < int_size )
+ {
+ // above 'if' is always true
+ // this is only to get rid of a warning "warning: array subscript is above array bounds"
+ // (from gcc)
+ // we checked the condition there: "if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )"
+ // but gcc doesn't understand our types - exponent is Int<>
+
+ for(uint i=0 ; i<man ; ++i)
+ result.table[index+i] = mantissa.table[i];
+ }
+
+ result.Rcl( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
+ }
+
+ return 0;
+ }
+
+
+public:
+
+ /*!
+ this method converts 'this' into 'result'
+
+ if the value is too big this method returns a carry (1)
+ */
+ template<uint int_size>
+ uint ToUInt(UInt<int_size> & result) const
+ {
+ uint c = ToUIntOrInt(result);
+
+ if( c )
+ return 1;
+
+ if( IsSign() )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts 'this' into 'result'
+
+ if the value is too big this method returns a carry (1)
+ */
+ template<uint int_size>
+ uint ToInt(UInt<int_size> & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts 'this' into 'result'
+
+ if the value is too big this method returns a carry (1)
+ */
+ template<uint int_size>
+ uint ToInt(Int<int_size> & result) const
+ {
+ uint c = ToUIntOrInt(result);
+
+ if( c )
+ return 1;
+
+ uint mask = 0;
+
+ if( IsSign() )
+ {
+ result.ChangeSign();
+ mask = TTMATH_UINT_MAX_VALUE;
+ }
+
+ return ((result.table[int_size-1] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT))? 0 : 1;
+ }
+
+
+ /*!
+ a method for converting 'uint' to this class
+ */
+ uint FromUInt(uint value)
+ {
+ if( value == 0 )
+ {
+ SetZero();
+ return 0;
+ }
+
+ info = 0;
+
+ for(uint i=0 ; i<man-1 ; ++i)
+ mantissa.table[i] = 0;
+
+ mantissa.table[man-1] = value;
+ exponent = -sint(man-1) * sint(TTMATH_BITS_PER_UINT);
+
+ // there shouldn't be a carry because 'value' has the 'uint' type
+ Standardizing();
+
+ return 0;
+ }
+
+
+ /*!
+ a method for converting 'uint' to this class
+ */
+ uint FromInt(uint value)
+ {
+ return FromUInt(value);
+ }
+
+
+ /*!
+ a method for converting 'sint' to this class
+ */
+ uint FromInt(sint value)
+ {
+ bool is_sign = false;
+
+ if( value < 0 )
+ {
+ value = -value;
+ is_sign = true;
+ }
+
+ FromUInt(uint(value));
+
+ if( is_sign )
+ SetSign();
+
+ return 0;
+ }
+
+
+
+ /*!
+ this method converts from standard double into this class
+
+ standard double means IEEE-754 floating point value with 64 bits
+ it is as follows (from http://www.psc.edu/general/software/packages/ieee/ieee.html):
+
+ The IEEE double precision floating point standard representation requires
+ a 64 bit word, which may be represented as numbered from 0 to 63, left to
+ right. The first bit is the sign bit, S, the next eleven bits are the
+ exponent bits, 'E', and the final 52 bits are the fraction 'F':
+
+ S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ 0 1 11 12 63
+
+ The value V represented by the word may be determined as follows:
+
+ * If E=2047 and F is nonzero, then V=NaN ("Not a number")
+ * If E=2047 and F is zero and S is 1, then V=-Infinity
+ * If E=2047 and F is zero and S is 0, then V=Infinity
+ * If 0<E<2047 then V=(-1)**S * 2 ** (E-1023) * (1.F) where "1.F" is intended
+ to represent the binary number created by prefixing F with an implicit
+ leading 1 and a binary point.
+ * If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-1022) * (0.F) These are
+ "unnormalized" values.
+ * If E=0 and F is zero and S is 1, then V=-0
+ * If E=0 and F is zero and S is 0, then V=0
+ */
+
+#ifdef TTMATH_PLATFORM32
+
+ uint FromDouble(double value)
+ {
+ // I am not sure what will be on a platform which has
+ // a different endianness... but we use this library only
+ // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
+ union
+ {
+ double d;
+ uint u[2]; // two 32bit words
+ } temp;
+
+ temp.d = value;
+
+ sint e = ( temp.u[1] & 0x7FF00000u) >> 20;
+ uint m1 = ((temp.u[1] & 0xFFFFFu) << 11) | (temp.u[0] >> 21);
+ uint m2 = temp.u[0] << 11;
+
+ if( e == 2047 )
+ {
+ // If E=2047 and F is nonzero, then V=NaN ("Not a number")
+ // If E=2047 and F is zero and S is 1, then V=-Infinity
+ // If E=2047 and F is zero and S is 0, then V=Infinity
+
+ // we do not support -Infinity and +Infinity
+ // we assume that there is always NaN
+
+ SetNan();
+ }
+ else
+ if( e > 0 )
+ {
+ // If 0<E<2047 then
+ // V=(-1)**S * 2 ** (E-1023) * (1.F)
+ // where "1.F" is intended to represent the binary number
+ // created by prefixing F with an implicit leading 1 and a binary point.
+
+ FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
+ e - 1023 - man*TTMATH_BITS_PER_UINT + 1, 0x80000000u,
+ m1, m2);
+
+ // we do not have to call Standardizing() here
+ // because the mantissa will have the highest bit set
+ }
+ else
+ {
+ // e == 0
+
+ if( m1 != 0 || m2 != 0 )
+ {
+ // If E=0 and F is nonzero,
+ // then V=(-1)**S * 2 ** (-1022) * (0.F)
+ // These are "unnormalized" values.
+
+ UInt<2> m;
+ m.table[1] = m1;
+ m.table[0] = m2;
+ uint moved = m.CompensationToLeft();
+
+ FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
+ e - 1022 - man*TTMATH_BITS_PER_UINT + 1 - moved, 0,
+ m.table[1], m.table[2]);
+ }
+ else
+ {
+ // If E=0 and F is zero and S is 1, then V=-0
+ // If E=0 and F is zero and S is 0, then V=0
+
+ // we do not support -0 or 0, only is one 0
+ SetZero();
+ }
+ }
+
+ return 0; // never be a carry
+ }
+
+
+private:
+
+ void FromDouble_SetExpAndMan(bool is_sign, int e, uint mhighest, uint m1, uint m2)
+ {
+ exponent = e;
+
+ if( man > 1 )
+ {
+ mantissa.table[man-1] = m1 | mhighest;
+ mantissa.table[sint(man-2)] = m2;
+ // although man>1 we're using casting into sint
+ // to get rid from a warning which generates Microsoft Visual:
+ // warning C4307: '*' : integral constant overflow
+
+ for(uint i=0 ; i<man-2 ; ++i)
+ mantissa.table[i] = 0;
+ }
+ else
+ {
+ mantissa.table[0] = m1 | mhighest;
+ }
+
+ info = 0;
+
+ // the value should be different from zero
+ TTMATH_ASSERT( mantissa.IsZero() == false )
+
+ if( is_sign )
+ SetSign();
+ }
+
+
+#else
+
+public:
+
+ // 64bit platforms
+ uint FromDouble(double value)
+ {
+ // I am not sure what will be on a plaltform which has
+ // a different endianness... but we use this library only
+ // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
+ union
+ {
+ double d;
+ uint u; // one 64bit word
+ } temp;
+
+ temp.d = value;
+
+ sint e = (temp.u & 0x7FF0000000000000ul) >> 52;
+ uint m = (temp.u & 0xFFFFFFFFFFFFFul) << 11;
+
+ if( e == 2047 )
+ {
+ // If E=2047 and F is nonzero, then V=NaN ("Not a number")
+ // If E=2047 and F is zero and S is 1, then V=-Infinity
+ // If E=2047 and F is zero and S is 0, then V=Infinity
+
+ // we do not support -Infinity and +Infinity
+ // we assume that there is always NaN
+
+ SetNan();
+ }
+ else
+ if( e > 0 )
+ {
+ // If 0<E<2047 then
+ // V=(-1)**S * 2 ** (E-1023) * (1.F)
+ // where "1.F" is intended to represent the binary number
+ // created by prefixing F with an implicit leading 1 and a binary point.
+
+ FromDouble_SetExpAndMan((temp.u & 0x8000000000000000ul) != 0,
+ e - 1023 - man*TTMATH_BITS_PER_UINT + 1,
+ 0x8000000000000000ul, m);
+
+ // we do not have to call Standardizing() here
+ // because the mantissa will have the highest bit set
+ }
+ else
+ {
+ // e == 0
+
+ if( m != 0 )
+ {
+ // If E=0 and F is nonzero,
+ // then V=(-1)**S * 2 ** (-1022) * (0.F)
+ // These are "unnormalized" values.
+
+ FromDouble_SetExpAndMan(bool(temp.u & 0x8000000000000000ul),
+ e - 1022 - man*TTMATH_BITS_PER_UINT + 1, 0, m);
+ Standardizing();
+ }
+ else
+ {
+ // If E=0 and F is zero and S is 1, then V=-0
+ // If E=0 and F is zero and S is 0, then V=0
+
+ // we do not support -0 or 0, only is one 0
+ SetZero();
+ }
+ }
+
+ return 0; // never be a carry
+ }
+
+private:
+
+ void FromDouble_SetExpAndMan(bool is_sign, sint e, uint mhighest, uint m)
+ {
+ exponent = e;
+ mantissa.table[man-1] = m | mhighest;
+
+ for(uint i=0 ; i<man-1 ; ++i)
+ mantissa.table[i] = 0;
+
+ info = 0;
+
+ // the value should be different from zero
+ TTMATH_ASSERT( mantissa.IsZero() == false )
+
+ if( is_sign )
+ SetSign();
+ }
+
+#endif
+
+
+public:
+
+
+ /*!
+ this method converts from float to this class
+ */
+ uint FromFloat(float value)
+ {
+ return FromDouble(double(value));
+ }
+
+
+ /*!
+ this method converts from this class into the 'double'
+
+ if the value is too big:
+ 'result' will be +/-infinity (depending on the sign)
+ if the value is too small:
+ 'result' will be 0
+ */
+ double ToDouble() const
+ {
+ double result;
+
+ ToDouble(result);
+
+ return result;
+ }
+
+
+private:
+
+
+ /*!
+ an auxiliary method to check if the float value is +/-infinity
+ we provide this method because isinf(float) in only in C99 language
+
+ description taken from: http://www.psc.edu/general/software/packages/ieee/ieee.php
+
+ The IEEE single precision floating point standard representation requires a 32 bit word,
+ which may be represented as numbered from 0 to 31, left to right.
+ The first bit is the sign bit, S, the next eight bits are the exponent bits, 'E',
+ and the final 23 bits are the fraction 'F':
+
+ S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
+ 0 1 8 9 31
+
+ The value V represented by the word may be determined as follows:
+
+ * If E=255 and F is nonzero, then V=NaN ("Not a number")
+ * If E=255 and F is zero and S is 1, then V=-Infinity
+ * If E=255 and F is zero and S is 0, then V=Infinity
+ * If 0<E<255 then V=(-1)**S * 2 ** (E-127) * (1.F) where "1.F" is intended to represent
+ the binary number created by prefixing F with an implicit leading 1 and a binary point.
+ * If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-126) * (0.F) These are "unnormalized" values.
+ * If E=0 and F is zero and S is 1, then V=-0
+ * If E=0 and F is zero and S is 0, then V=0
+ */
+ bool IsInf(float value) const
+ {
+ // need testing on a 64 bit machine
+
+ union
+ {
+ float d;
+ uint u;
+ } temp;
+
+ temp.d = value;
+
+ if( ((temp.u >> 23) & 0xff) == 0xff )
+ {
+ if( (temp.u & 0x7FFFFF) == 0 )
+ return true; // +/- infinity
+ }
+
+ return false;
+ }
+
+
+public:
+
+ /*!
+ this method converts from this class into the 'float'
+
+ if the value is too big:
+ 'result' will be +/-infinity (depending on the sign)
+ if the value is too small:
+ 'result' will be 0
+ */
+ float ToFloat() const
+ {
+ float result;
+
+ ToFloat(result);
+
+ return result;
+ }
+
+
+ /*!
+ this method converts from this class into the 'float'
+
+ if the value is too big:
+ 'result' will be +/-infinity (depending on the sign)
+ and the method returns 1
+ if the value is too small:
+ 'result' will be 0
+ and the method returns 1
+ */
+ uint ToFloat(float & result) const
+ {
+ double result_double;
+
+ uint c = ToDouble(result_double);
+ result = float(result_double);
+
+ if( result == -0.0f )
+ result = 0.0f;
+
+ if( c )
+ return 1;
+
+ // although the result_double can have a correct value
+ // but after converting to float there can be infinity
+
+ if( IsInf(result) )
+ return 1;
+
+ if( result == 0.0f && result_double != 0.0 )
+ // result_double was too small for float
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts from this class into the 'double'
+
+ if the value is too big:
+ 'result' will be +/-infinity (depending on the sign)
+ and the method returns 1
+ if the value is too small:
+ 'result' will be 0
+ and the method returns 1
+ */
+ uint ToDouble(double & result) const
+ {
+ if( IsZero() )
+ {
+ result = 0.0;
+ return 0;
+ }
+
+ if( IsNan() )
+ {
+ result = ToDouble_SetDouble( false, 2047, 0, false, true);
+
+ return 0;
+ }
+
+ sint e_correction = sint(man*TTMATH_BITS_PER_UINT) - 1;
+
+ if( exponent >= 1024 - e_correction )
+ {
+ // +/- infinity
+ result = ToDouble_SetDouble( IsSign(), 2047, 0, true);
+
+ return 1;
+ }
+ else
+ if( exponent <= -1023 - 52 - e_correction )
+ {
+ // too small value - we assume that there'll be a zero
+ result = 0;
+
+ // and return a carry
+ return 1;
+ }
+
+ sint e = exponent.ToInt() + e_correction;
+
+ if( e <= -1023 )
+ {
+ // -1023-52 < e <= -1023 (unnormalized value)
+ result = ToDouble_SetDouble( IsSign(), 0, -(e + 1023));
+ }
+ else
+ {
+ // -1023 < e < 1024
+ result = ToDouble_SetDouble( IsSign(), e + 1023, -1);
+ }
+
+ return 0;
+ }
+
+private:
+
+#ifdef TTMATH_PLATFORM32
+
+ // 32bit platforms
+ double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
+ {
+ union
+ {
+ double d;
+ uint u[2]; // two 32bit words
+ } temp;
+
+ temp.u[0] = temp.u[1] = 0;
+
+ if( is_sign )
+ temp.u[1] |= 0x80000000u;
+
+ temp.u[1] |= (e << 20) & 0x7FF00000u;
+
+ if( nan )
+ {
+ temp.u[0] |= 1;
+ return temp.d;
+ }
+
+ if( infinity )
+ return temp.d;
+
+ UInt<2> m;
+ m.table[1] = mantissa.table[man-1];
+ m.table[0] = ( man > 1 ) ? mantissa.table[sint(man-2)] : 0;
+ // although man>1 we're using casting into sint
+ // to get rid from a warning which generates Microsoft Visual:
+ // warning C4307: '*' : integral constant overflow
+
+ m.Rcr( 12 + move );
+ m.table[1] &= 0xFFFFFu; // cutting the 20 bit (when 'move' was -1)
+
+ temp.u[1] |= m.table[1];
+ temp.u[0] |= m.table[0];
+
+ return temp.d;
+ }
+
+#else
+
+ // 64bit platforms
+ double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
+ {
+ union
+ {
+ double d;
+ uint u; // 64bit word
+ } temp;
+
+ temp.u = 0;
+
+ if( is_sign )
+ temp.u |= 0x8000000000000000ul;
+
+ temp.u |= (e << 52) & 0x7FF0000000000000ul;
+
+ if( nan )
+ {
+ temp.u |= 1;
+ return temp.d;
+ }
+
+ if( infinity )
+ return temp.d;
+
+ uint m = mantissa.table[man-1];
+
+ m >>= ( 12 + move );
+ m &= 0xFFFFFFFFFFFFFul; // cutting the 20 bit (when 'move' was -1)
+ temp.u |= m;
+
+ return temp.d;
+ }
+
+#endif
+
+
+public:
+
+
+ /*!
+ an operator= for converting 'sint' to this class
+ */
+ Big<exp, man> & operator=(sint value)
+ {
+ FromInt(value);
+
+ return *this;
+ }
+
+
+ /*!
+ an operator= for converting 'uint' to this class
+ */
+ Big<exp, man> & operator=(uint value)
+ {
+ FromUInt(value);
+
+ return *this;
+ }
+
+
+ /*!
+ an operator= for converting 'float' to this class
+ */
+ Big<exp, man> & operator=(float value)
+ {
+ FromFloat(value);
+
+ return *this;
+ }
+
+
+ /*!
+ an operator= for converting 'double' to this class
+ */
+ Big<exp, man> & operator=(double value)
+ {
+ FromDouble(value);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting 'sint' to this class
+ */
+ Big(sint value)
+ {
+ FromInt(value);
+ }
+
+ /*!
+ a constructor for converting 'uint' to this class
+ */
+ Big(uint value)
+ {
+ FromUInt(value);
+ }
+
+
+ /*!
+ a constructor for converting 'double' to this class
+ */
+ Big(double value)
+ {
+ FromDouble(value);
+ }
+
+
+ /*!
+ a constructor for converting 'float' to this class
+ */
+ Big(float value)
+ {
+ FromFloat(value);
+ }
+
+
+#ifdef TTMATH_PLATFORM32
+
+ /*!
+ this method converts 'this' into 'result' (64 bit unsigned integer)
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToUInt(ulint & result) const
+ {
+ UInt<2> temp; // 64 bits container
+
+ uint c = ToUInt(temp);
+ temp.ToUInt(result);
+
+ return c;
+ }
+
+
+ /*!
+ this method converts 'this' into 'result' (64 bit unsigned integer)
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToInt(ulint & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts 'this' into 'result' (64 bit unsigned integer)
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToInt(slint & result) const
+ {
+ Int<2> temp; // 64 bits container
+
+ uint c = ToInt(temp);
+ temp.ToInt(result);
+
+ return c;
+ }
+
+
+ /*!
+ a method for converting 'ulint' (64bit unsigned integer) to this class
+ */
+ uint FromUInt(ulint value)
+ {
+ if( value == 0 )
+ {
+ SetZero();
+ return 0;
+ }
+
+ info = 0;
+
+ if( man == 1 )
+ {
+ sint bit = mantissa.FindLeadingBitInWord(uint(value >> TTMATH_BITS_PER_UINT));
+
+ if( bit != -1 )
+ {
+ // the highest word from value is different from zero
+ bit += 1;
+ value >>= bit;
+ exponent = bit;
+ }
+ else
+ {
+ exponent.SetZero();
+ }
+
+ mantissa.table[0] = uint(value);
+ }
+ else
+ {
+ #ifdef _MSC_VER
+ //warning C4307: '*' : integral constant overflow
+ #pragma warning( disable: 4307 )
+ #endif
+
+ // man >= 2
+ mantissa.table[man-1] = uint(value >> TTMATH_BITS_PER_UINT);
+ mantissa.table[man-2] = uint(value);
+
+ #ifdef _MSC_VER
+ //warning C4307: '*' : integral constant overflow
+ #pragma warning( default: 4307 )
+ #endif
+
+ exponent = -sint(man-2) * sint(TTMATH_BITS_PER_UINT);
+
+ for(uint i=0 ; i<man-2 ; ++i)
+ mantissa.table[i] = 0;
+ }
+
+ // there shouldn't be a carry because 'value' has the 'ulint' type
+ // (we have sufficient exponent)
+ Standardizing();
+
+ return 0;
+ }
+
+
+ /*!
+ a method for converting 'ulint' (64bit unsigned integer) to this class
+ */
+ uint FromInt(ulint value)
+ {
+ return FromUInt(value);
+ }
+
+
+ /*!
+ a method for converting 'slint' (64bit signed integer) to this class
+ */
+ uint FromInt(slint value)
+ {
+ bool is_sign = false;
+
+ if( value < 0 )
+ {
+ value = -value;
+ is_sign = true;
+ }
+
+ FromUInt(ulint(value));
+
+ if( is_sign )
+ SetSign();
+
+ return 0;
+ }
+
+
+ /*!
+ a constructor for converting 'ulint' (64bit unsigned integer) to this class
+ */
+ Big(ulint value)
+ {
+ FromUInt(value);
+ }
+
+
+ /*!
+ an operator for converting 'ulint' (64bit unsigned integer) to this class
+ */
+ Big<exp, man> & operator=(ulint value)
+ {
+ FromUInt(value);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting 'slint' (64bit signed integer) to this class
+ */
+ Big(slint value)
+ {
+ FromInt(value);
+ }
+
+
+ /*!
+ an operator for converting 'slint' (64bit signed integer) to this class
+ */
+ Big<exp, man> & operator=(slint value)
+ {
+ FromInt(value);
+
+ return *this;
+ }
+
+#endif
+
+
+
+#ifdef TTMATH_PLATFORM64
+
+
+ /*!
+ this method converts 'this' into 'result' (32 bit unsigned integer)
+ ***this method is created only on a 64bit platform***
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToUInt(unsigned int & result) const
+ {
+ uint result_uint;
+
+ uint c = ToUInt(result_uint);
+ result = (unsigned int)result_uint;
+
+ if( c || result_uint != uint(result) )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts 'this' into 'result' (32 bit unsigned integer)
+ ***this method is created only on a 64bit platform***
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToInt(unsigned int & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts 'this' into 'result' (32 bit signed integer)
+ ***this method is created only on a 64bit platform***
+ if the value is too big this method returns a carry (1)
+ */
+ uint ToInt(signed int & result) const
+ {
+ sint result_sint;
+
+ uint c = ToInt(result_sint);
+ result = (signed int)result_sint;
+
+ if( c || result_sint != sint(result) )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*
+ this method converts 32 bit unsigned int to this class
+ ***this method is created only on a 64bit platform***
+ */
+ uint FromUInt(unsigned int value)
+ {
+ return FromUInt(uint(value));
+ }
+
+
+ /*
+ this method converts 32 bit unsigned int to this class
+ ***this method is created only on a 64bit platform***
+ */
+ uint FromInt(unsigned int value)
+ {
+ return FromUInt(uint(value));
+ }
+
+
+ /*
+ this method converts 32 bit signed int to this class
+ ***this method is created only on a 64bit platform***
+ */
+ uint FromInt(signed int value)
+ {
+ return FromInt(sint(value));
+ }
+
+
+ /*!
+ an operator= for converting 32 bit unsigned int to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ Big<exp, man> & operator=(unsigned int value)
+ {
+ FromUInt(value);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting 32 bit unsigned int to this class
+ ***this constructor is created only on a 64bit platform***
+ */
+ Big(unsigned int value)
+ {
+ FromUInt(value);
+ }
+
+
+ /*!
+ an operator for converting 32 bit signed int to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ Big<exp, man> & operator=(signed int value)
+ {
+ FromInt(value);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting 32 bit signed int to this class
+ ***this constructor is created only on a 64bit platform***
+ */
+ Big(signed int value)
+ {
+ FromInt(value);
+ }
+
+#endif
+
+
+private:
+
+ /*!
+ an auxiliary method for converting from UInt and Int
+
+ we assume that there'll never be a carry here
+ (we have an exponent and the value in Big can be bigger than
+ that one from the UInt)
+ */
+ template<uint int_size>
+ uint FromUIntOrInt(const UInt<int_size> & value, sint compensation)
+ {
+ uint minimum_size = (int_size < man)? int_size : man;
+ exponent = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation;
+
+ // copying the highest words
+ uint i;
+ for(i=1 ; i<=minimum_size ; ++i)
+ mantissa.table[man-i] = value.table[int_size-i];
+
+ // setting the rest of mantissa.table into zero (if some has left)
+ for( ; i<=man ; ++i)
+ mantissa.table[man-i] = 0;
+
+ // the highest bit is either one or zero (when the whole mantissa is zero)
+ // we can only call CorrectZero()
+ CorrectZero();
+
+ return 0;
+ }
+
+
+public:
+
+ /*!
+ a method for converting from 'UInt<int_size>' to this class
+ */
+ template<uint int_size>
+ uint FromUInt(UInt<int_size> value)
+ {
+ info = 0;
+ sint compensation = (sint)value.CompensationToLeft();
+
+ return FromUIntOrInt(value, compensation);
+ }
+
+
+ /*!
+ a method for converting from 'UInt<int_size>' to this class
+ */
+ template<uint int_size>
+ uint FromInt(const UInt<int_size> & value)
+ {
+ return FromUInt(value);
+ }
+
+
+ /*!
+ a method for converting from 'Int<int_size>' to this class
+ */
+ template<uint int_size>
+ uint FromInt(Int<int_size> value)
+ {
+ info = 0;
+ bool is_sign = false;
+
+ if( value.IsSign() )
+ {
+ value.ChangeSign();
+ is_sign = true;
+ }
+
+ sint compensation = (sint)value.CompensationToLeft();
+ FromUIntOrInt(value, compensation);
+
+ if( is_sign )
+ SetSign();
+
+ return 0;
+ }
+
+
+ /*!
+ an operator= for converting from 'Int<int_size>' to this class
+ */
+ template<uint int_size>
+ Big<exp,man> & operator=(const Int<int_size> & value)
+ {
+ FromInt(value);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting from 'Int<int_size>' to this class
+ */
+ template<uint int_size>
+ Big(const Int<int_size> & value)
+ {
+ FromInt(value);
+ }
+
+
+ /*!
+ an operator= for converting from 'UInt<int_size>' to this class
+ */
+ template<uint int_size>
+ Big<exp,man> & operator=(const UInt<int_size> & value)
+ {
+ FromUInt(value);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting from 'UInt<int_size>' to this class
+ */
+ template<uint int_size>
+ Big(const UInt<int_size> & value)
+ {
+ FromUInt(value);
+ }
+
+
+ /*!
+ an operator= for converting from 'Big<another_exp, another_man>' to this class
+ */
+ template<uint another_exp, uint another_man>
+ Big<exp,man> & operator=(const Big<another_exp, another_man> & value)
+ {
+ FromBig(value);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting from 'Big<another_exp, another_man>' to this class
+ */
+ template<uint another_exp, uint another_man>
+ Big(const Big<another_exp, another_man> & value)
+ {
+ FromBig(value);
+ }
+
+
+ /*!
+ a default constructor
+
+ by default we don't set any of the members to zero
+ only NaN flag is set
+
+ if you want the mantissa and exponent to be set to zero
+ define TTMATH_BIG_DEFAULT_CLEAR macro
+ (useful for debug purposes)
+ */
+ Big()
+ {
+ #ifdef TTMATH_BIG_DEFAULT_CLEAR
+
+ SetZeroNan();
+
+ #else
+
+ info = TTMATH_BIG_NAN;
+ // we're directly setting 'info' (instead of calling SetNan())
+ // in order to get rid of a warning saying that 'info' is uninitialized
+
+ #endif
+ }
+
+
+ /*!
+ a destructor
+ */
+ ~Big()
+ {
+ }
+
+
+ /*!
+ the default assignment operator
+ */
+ Big<exp,man> & operator=(const Big<exp,man> & value)
+ {
+ info = value.info;
+ exponent = value.exponent;
+ mantissa = value.mantissa;
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for copying from another object of this class
+ */
+
+ Big(const Big<exp,man> & value)
+ {
+ operator=(value);
+ }
+
+
+
+ /*!
+ a method for converting into a string
+ struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+
+ output:
+ return value:
+ 0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
+ 1 - if there is a carry (it shoudn't be in a normal situation - if it is that means there
+ is somewhere an error in the library)
+ */
+ uint ToString( std::string & result,
+ uint base = 10,
+ bool scient = false,
+ sint scient_from = 15,
+ sint round = -1,
+ bool trim_zeroes = true,
+ char comma = '.' ) const
+ {
+ Conv conv;
+
+ conv.base = base;
+ conv.scient = scient;
+ conv.scient_from = scient_from;
+ conv.round = round;
+ conv.trim_zeroes = trim_zeroes;
+ conv.comma = static_cast<uint>(comma);
+
+ return ToStringBase<std::string, char>(result, conv);
+ }
+
+
+ /*!
+ a method for converting into a string
+ struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+ */
+ uint ToString(std::string & result, const Conv & conv) const
+ {
+ return ToStringBase<std::string, char>(result, conv);
+ }
+
+
+ /*!
+ a method for converting into a string
+ struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+ */
+ std::string ToString(const Conv & conv) const
+ {
+ std::string result;
+ ToStringBase<std::string, char>(result, conv);
+
+ return result;
+ }
+
+
+ /*!
+ a method for converting into a string
+ struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+ */
+ std::string ToString(uint base = 10) const
+ {
+ Conv conv;
+ conv.base = base;
+
+ return ToString(conv);
+ }
+
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+
+ /*!
+ a method for converting into a string
+ struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+ */
+ uint ToString( std::wstring & result,
+ uint base = 10,
+ bool scient = false,
+ sint scient_from = 15,
+ sint round = -1,
+ bool trim_zeroes = true,
+ wchar_t comma = '.' ) const
+ {
+ Conv conv;
+
+ conv.base = base;
+ conv.scient = scient;
+ conv.scient_from = scient_from;
+ conv.round = round;
+ conv.trim_zeroes = trim_zeroes;
+ conv.comma = static_cast<uint>(comma);
+
+ return ToStringBase<std::wstring, wchar_t>(result, conv);
+ }
+
+
+ /*!
+ a method for converting into a string
+ struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+ */
+ uint ToString(std::wstring & result, const Conv & conv) const
+ {
+ return ToStringBase<std::wstring, wchar_t>(result, conv);
+ }
+
+
+ /*!
+ a method for converting into a string
+ struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+ */
+ std::wstring ToWString(const Conv & conv) const
+ {
+ std::wstring result;
+ ToStringBase<std::wstring, wchar_t>(result, conv);
+
+ return result;
+ }
+
+
+ /*!
+ a method for converting into a string
+ struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+ */
+ std::wstring ToWString(uint base = 10) const
+ {
+ Conv conv;
+ conv.base = base;
+
+ return ToWString(conv);
+ }
+
+#endif
+
+
+
+private:
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ uint ToStringBase(string_type & result, const Conv & conv) const
+ {
+ static char error_overflow_msg[] = "overflow";
+ static char error_nan_msg[] = "NaN";
+ result.erase();
+
+ if( IsNan() )
+ {
+ Misc::AssignString(result, error_nan_msg);
+ return 0;
+ }
+
+ if( conv.base<2 || conv.base>16 )
+ {
+ Misc::AssignString(result, error_overflow_msg);
+ return 1;
+ }
+
+ if( IsZero() )
+ {
+ result = '0';
+
+ return 0;
+ }
+
+ /*
+ since 'base' is greater or equal 2 that 'new_exp' of type 'Int<exp>' should
+ hold the new value of exponent but we're using 'Int<exp+1>' because
+ if the value for example would be 'max()' then we couldn't show it
+
+ max() -> 11111111 * 2 ^ 11111111111 (bin)(the mantissa and exponent have all bits set)
+ if we were using 'Int<exp>' we couldn't show it in this format:
+ 1,1111111 * 2 ^ 11111111111 (bin)
+ because we have to add something to the mantissa and because
+ mantissa is full we can't do it and it'll be a carry
+ (look at ToString_SetCommaAndExponent(...))
+
+ when the base would be greater than two (for example 10)
+ we could use 'Int<exp>' here
+ */
+ Int<exp+1> new_exp;
+
+ if( ToString_CreateNewMantissaAndExponent<string_type, char_type>(result, conv, new_exp) )
+ {
+ Misc::AssignString(result, error_overflow_msg);
+ return 1;
+ }
+
+
+ if( ToString_SetCommaAndExponent<string_type, char_type>(result, conv, new_exp) )
+ {
+ Misc::AssignString(result, error_overflow_msg);
+ return 1;
+ }
+
+ if( IsSign() )
+ result.insert(result.begin(), '-');
+
+
+ // converted successfully
+ return 0;
+ }
+
+
+
+ /*!
+ in the method 'ToString_CreateNewMantissaAndExponent()' we're using
+ type 'Big<exp+1,man>' and we should have the ability to use some
+ necessary methods from that class (methods which are private here)
+ */
+ friend class Big<exp-1,man>;
+
+
+ /*!
+ an auxiliary method for converting into the string
+
+ input:
+ base - the base in range <2,16>
+
+ output:
+ return values:
+ 0 - ok
+ 1 - if there was a carry
+ new_man - the new mantissa for 'base'
+ new_exp - the new exponent for 'base'
+
+ mathematic part:
+
+ the value is stored as:
+ value = mantissa * 2^exponent
+ we want to show 'value' as:
+ value = new_man * base^new_exp
+
+ then 'new_man' we'll print using the standard method from UInt<> type for printing
+ and 'new_exp' is the offset of the comma operator in a system of a base 'base'
+
+ value = mantissa * 2^exponent
+ value = mantissa * 2^exponent * (base^new_exp / base^new_exp)
+ value = mantissa * (2^exponent / base^new_exp) * base^new_exp
+
+ look at the part (2^exponent / base^new_exp), there'll be good if we take
+ a 'new_exp' equal that value when the (2^exponent / base^new_exp) will be equal one
+
+ on account of the 'base' is not as power of 2 (can be from 2 to 16),
+ this formula will not be true for integer 'new_exp' then in our case we take
+ 'base^new_exp' _greater_ than '2^exponent'
+
+ if 'base^new_exp' were smaller than '2^exponent' the new mantissa could be
+ greater than the max value of the container UInt<man>
+
+ value = mantissa * (2^exponent / base^new_exp) * base^new_exp
+ let M = mantissa * (2^exponent / base^new_exp) then
+ value = M * base^new_exp
+
+ in our calculation we treat M as floating value showing it as:
+ M = mm * 2^ee where ee will be <= 0
+
+ next we'll move all bits of mm into the right when ee is equal zero
+ abs(ee) must not be too big that only few bits from mm we can leave
+
+ then we'll have:
+ M = mmm * 2^0
+ 'mmm' is the new_man which we're looking for
+
+
+ new_exp we calculate in this way:
+ 2^exponent <= base^new_exp
+ new_exp >= log base (2^exponent) <- logarithm with the base 'base' from (2^exponent)
+
+ but we need new_exp as integer then we test:
+ if new_exp is greater than zero and with fraction we add one to new_exp
+ new_exp = new_exp + 1 (if new_exp>0 and with fraction)
+ and at the end we take the integer part:
+ new_exp = int(new_exp)
+ */
+ template<class string_type, class char_type>
+ uint ToString_CreateNewMantissaAndExponent( string_type & new_man, const Conv & conv,
+ Int<exp+1> & new_exp) const
+ {
+ uint c = 0;
+
+ if( conv.base<2 || conv.base>16 )
+ return 1;
+
+ // special method for base equal 2
+ if( conv.base == 2 )
+ return ToString_CreateNewMantissaAndExponent_Base2(new_man, new_exp);
+
+ // special method for base equal 4
+ if( conv.base == 4 )
+ return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 2);
+
+ // special method for base equal 8
+ if( conv.base == 8 )
+ return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 3);
+
+ // special method for base equal 16
+ if( conv.base == 16 )
+ return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 4);
+
+
+ // this = mantissa * 2^exponent
+
+ // temp = +1 * 2^exponent
+ // we're using a bigger type than 'big<exp,man>' (look below)
+ Big<exp+1,man> temp;
+ temp.info = 0;
+ temp.exponent = exponent;
+ temp.mantissa.SetOne();
+ c += temp.Standardizing();
+
+ // new_exp_ = log base (2^exponent)
+ // if new_exp_ is positive and with fraction then we add one
+ Big<exp+1,man> new_exp_;
+ c += new_exp_.ToString_Log(temp, conv.base); // this logarithm isn't very complicated
+
+ // rounding up to the nearest integer
+ if( !new_exp_.IsInteger() )
+ {
+ if( !new_exp_.IsSign() )
+ c += new_exp_.AddOne(); // new_exp_ > 0 and with fraction
+
+ new_exp_.SkipFraction();
+ }
+
+ if( ToString_CreateNewMantissaTryExponent<string_type, char_type>(new_man, conv, new_exp_, new_exp) )
+ {
+ // in very rare cases there can be an overflow from ToString_CreateNewMantissaTryExponent
+ // it means that new_exp_ was too small (the problem comes from floating point numbers precision)
+ // so we increse new_exp_ and try again
+ new_exp_.AddOne();
+ c += ToString_CreateNewMantissaTryExponent<string_type, char_type>(new_man, conv, new_exp_, new_exp);
+ }
+
+ return (c==0)? 0 : 1;
+ }
+
+
+
+ /*!
+ an auxiliary method for converting into the string
+
+ trying to calculate new_man for given exponent (new_exp_)
+ if there is a carry it can mean that new_exp_ is too small
+ */
+ template<class string_type, class char_type>
+ uint ToString_CreateNewMantissaTryExponent( string_type & new_man, const Conv & conv,
+ const Big<exp+1,man> & new_exp_, Int<exp+1> & new_exp) const
+ {
+ uint c = 0;
+
+ // because 'base^new_exp' is >= '2^exponent' then
+ // because base is >= 2 then we've got:
+ // 'new_exp_' must be smaller or equal 'new_exp'
+ // and we can pass it into the Int<exp> type
+ // (in fact we're using a greater type then it'll be ok)
+ c += new_exp_.ToInt(new_exp);
+
+ // base_ = base
+ Big<exp+1,man> base_(conv.base);
+
+ // base_ = base_ ^ new_exp_
+ c += base_.Pow( new_exp_ ); // use new_exp_ so Pow(Big<> &) version will be used
+ // if we hadn't used a bigger type than 'Big<exp,man>' then the result
+ // of this formula 'Pow(...)' would have been with an overflow
+
+ // temp = mantissa * 2^exponent / base_^new_exp_
+ Big<exp+1,man> temp;
+ temp.info = 0;
+ temp.mantissa = mantissa;
+ temp.exponent = exponent;
+ c += temp.Div(base_);
+
+ // moving all bits of the mantissa into the right
+ // (how many times to move depend on the exponent)
+ c += temp.ToString_MoveMantissaIntoRight();
+
+ // because we took 'new_exp' as small as it was
+ // possible ([log base (2^exponent)] + 1) that after the division
+ // (temp.Div( base_ )) the value of exponent should be equal zero or
+ // minimum smaller than zero then we've got the mantissa which has
+ // maximum valid bits
+ temp.mantissa.ToString(new_man, conv.base);
+
+ if( IsInteger() )
+ {
+ // making sure the new mantissa will be without fraction (integer)
+ ToString_CheckMantissaInteger<string_type, char_type>(new_man, new_exp);
+ }
+ else
+ if( conv.base_round )
+ {
+ c += ToString_BaseRound<string_type, char_type>(new_man, conv, new_exp);
+ }
+
+ return (c==0)? 0 : 1;
+ }
+
+
+ /*!
+ this method calculates the logarithm
+ it is used by ToString_CreateNewMantissaAndExponent() method
+
+ it's not too complicated
+ because x=+1*2^exponent (mantissa is one) then during the calculation
+ the Ln(x) will not be making the long formula from LnSurrounding1()
+ and only we have to calculate 'Ln(base)' but it'll be calculated
+ only once, the next time we will get it from the 'history'
+
+ x is greater than 0
+ base is in <2,16> range
+ */
+ uint ToString_Log(const Big<exp,man> & x, uint base)
+ {
+ TTMATH_REFERENCE_ASSERT( x )
+ TTMATH_ASSERT( base>=2 && base<=16 )
+
+ Big<exp,man> temp;
+ temp.SetOne();
+
+ if( x == temp )
+ {
+ // log(1) is 0
+ SetZero();
+
+ return 0;
+ }
+
+ // there can be only a carry
+ // because the 'x' is in '1+2*exponent' form then
+ // the long formula from LnSurrounding1() will not be calculated
+ // (LnSurrounding1() will return one immediately)
+ uint c = Ln(x);
+
+ if( base==10 && man<=TTMATH_BUILTIN_VARIABLES_SIZE )
+ {
+ // for the base equal 10 we're using SetLn10() instead of calculating it
+ // (only if we have the constant sufficient big)
+ temp.SetLn10();
+ }
+ else
+ {
+ c += ToString_LogBase(base, temp);
+ }
+
+ c += Div( temp );
+
+ return (c==0)? 0 : 1;
+ }
+
+
+#ifndef TTMATH_MULTITHREADS
+
+ /*!
+ this method calculates the logarithm of 'base'
+ it's used in single thread environment
+ */
+ uint ToString_LogBase(uint base, Big<exp,man> & result)
+ {
+ TTMATH_ASSERT( base>=2 && base<=16 )
+
+ // this guardians are initialized before the program runs (static POD types)
+ static int guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ static Big<exp,man> log_history[15];
+ uint index = base - 2;
+ uint c = 0;
+
+ if( guardians[index] == 0 )
+ {
+ Big<exp,man> base_(base);
+ c += log_history[index].Ln(base_);
+ guardians[index] = 1;
+ }
+
+ result = log_history[index];
+
+ return (c==0)? 0 : 1;
+ }
+
+#else
+
+ /*!
+ this method calculates the logarithm of 'base'
+ it's used in multi-thread environment
+ */
+ uint ToString_LogBase(uint base, Big<exp,man> & result)
+ {
+ TTMATH_ASSERT( base>=2 && base<=16 )
+
+ // this guardians are initialized before the program runs (static POD types)
+ volatile static sig_atomic_t guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ static Big<exp,man> * plog_history;
+ uint index = base - 2;
+ uint c = 0;
+
+ // double-checked locking
+ if( guardians[index] == 0 )
+ {
+ ThreadLock thread_lock;
+
+ // locking
+ if( thread_lock.Lock() )
+ {
+ static Big<exp,man> log_history[15];
+
+ if( guardians[index] == 0 )
+ {
+ plog_history = log_history;
+
+ Big<exp,man> base_(base);
+ c += log_history[index].Ln(base_);
+ guardians[index] = 1;
+ }
+ }
+ else
+ {
+ // there was a problem with locking, we store the result directly in 'result' object
+ Big<exp,man> base_(base);
+ c += result.Ln(base_);
+
+ return (c==0)? 0 : 1;
+ }
+
+ // automatically unlocking
+ }
+
+ result = plog_history[index];
+
+ return (c==0)? 0 : 1;
+ }
+
+#endif
+
+ /*!
+ an auxiliary method for converting into the string (private)
+
+ this method moving all bits from mantissa into the right side
+ the exponent tell us how many times moving (the exponent is <=0)
+ */
+ uint ToString_MoveMantissaIntoRight()
+ {
+ if( exponent.IsZero() )
+ return 0;
+
+ // exponent can't be greater than zero
+ // because we would cat the highest bits of the mantissa
+ if( !exponent.IsSign() )
+ return 1;
+
+
+ if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
+ // if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
+ // it means that we must cut the whole mantissa
+ // (there'll not be any of the valid bits)
+ return 1;
+
+ // e will be from (-man*TTMATH_BITS_PER_UINT, 0>
+ sint e = -( exponent.ToInt() );
+ mantissa.Rcr(e,0);
+
+ return 0;
+ }
+
+
+ /*!
+ a special method similar to the 'ToString_CreateNewMantissaAndExponent'
+ when the 'base' is equal 2
+
+ we use it because if base is equal 2 we don't have to make those
+ complicated calculations and the output is directly from the source
+ (there will not be any small distortions)
+ */
+ template<class string_type>
+ uint ToString_CreateNewMantissaAndExponent_Base2( string_type & new_man,
+ Int<exp+1> & new_exp ) const
+ {
+ for( sint i=man-1 ; i>=0 ; --i )
+ {
+ uint value = mantissa.table[i];
+
+ for( uint bit=0 ; bit<TTMATH_BITS_PER_UINT ; ++bit )
+ {
+ if( (value & TTMATH_UINT_HIGHEST_BIT) != 0 )
+ new_man += '1';
+ else
+ new_man += '0';
+
+ value <<= 1;
+ }
+ }
+
+ new_exp = exponent;
+
+ return 0;
+ }
+
+
+ /*!
+ a special method used to calculate the new mantissa and exponent
+ when the 'base' is equal 4, 8 or 16
+
+ when base is 4 then bits is 2
+ when base is 8 then bits is 3
+ when base is 16 then bits is 4
+ (and the algorithm can be used with a base greater than 16)
+ */
+ template<class string_type>
+ uint ToString_CreateNewMantissaAndExponent_BasePow2( string_type & new_man,
+ Int<exp+1> & new_exp,
+ uint bits) const
+ {
+ sint move; // how many times move the mantissa
+ UInt<man+1> man_temp(mantissa); // man+1 for moving
+ new_exp = exponent;
+ new_exp.DivInt((sint)bits, move);
+
+ if( move != 0 )
+ {
+ // we're moving the man_temp to left-hand side
+ if( move < 0 )
+ {
+ move = sint(bits) + move;
+ new_exp.SubOne(); // when move is < than 0 then new_exp is < 0 too
+ }
+
+ man_temp.Rcl(move);
+ }
+
+
+ if( bits == 3 )
+ {
+ // base 8
+ // now 'move' is greater than or equal 0
+ uint len = man*TTMATH_BITS_PER_UINT + move;
+ return ToString_CreateNewMantissaAndExponent_Base8(new_man, man_temp, len, bits);
+ }
+ else
+ {
+ // base 4 or 16
+ return ToString_CreateNewMantissaAndExponent_Base4or16(new_man, man_temp, bits);
+ }
+ }
+
+
+ /*!
+ a special method used to calculate the new mantissa
+ when the 'base' is equal 8
+
+ bits is always 3
+
+ we can use this algorithm when the base is 4 or 16 too
+ but we have a faster method ToString_CreateNewMantissaAndExponent_Base4or16()
+ */
+ template<class string_type>
+ uint ToString_CreateNewMantissaAndExponent_Base8( string_type & new_man,
+ UInt<man+1> & man_temp,
+ uint len,
+ uint bits) const
+ {
+ uint shift = TTMATH_BITS_PER_UINT - bits;
+ uint mask = TTMATH_UINT_MAX_VALUE >> shift;
+ uint i;
+
+ for( i=0 ; i<len ; i+=bits )
+ {
+ uint digit = man_temp.table[0] & mask;
+ new_man.insert(new_man.begin(), static_cast<char>(Misc::DigitToChar(digit)));
+
+ man_temp.Rcr(bits);
+ }
+
+ TTMATH_ASSERT( man_temp.IsZero() )
+
+ return 0;
+ }
+
+
+ /*!
+ a special method used to calculate the new mantissa
+ when the 'base' is equal 4 or 16
+
+ when the base is equal 4 or 16 the bits is 2 or 4
+ and because TTMATH_BITS_PER_UINT (32 or 64) is divisible by 2 (or 4)
+ then we can get digits from the end of our mantissa
+ */
+ template<class string_type>
+ uint ToString_CreateNewMantissaAndExponent_Base4or16( string_type & new_man,
+ UInt<man+1> & man_temp,
+ uint bits) const
+ {
+ TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 2 == 0 )
+ TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 4 == 0 )
+
+ uint shift = TTMATH_BITS_PER_UINT - bits;
+ uint mask = TTMATH_UINT_MAX_VALUE << shift;
+ uint digit;
+
+ // table[man] - last word - is different from zero if we moved man_temp
+ digit = man_temp.table[man];
+
+ if( digit != 0 )
+ new_man += static_cast<char>(Misc::DigitToChar(digit));
+
+
+ for( int i=man-1 ; i>=0 ; --i )
+ {
+ uint shift_local = shift;
+ uint mask_local = mask;
+
+ while( mask_local != 0 )
+ {
+ digit = man_temp.table[i] & mask_local;
+
+ if( shift_local != 0 )
+ digit = digit >> shift_local;
+
+ new_man += static_cast<char>(Misc::DigitToChar(digit));
+ mask_local = mask_local >> bits;
+ shift_local = shift_local - bits;
+ }
+ }
+
+ return 0;
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ bool ToString_RoundMantissaWouldBeInteger(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
+ {
+ // if new_exp is greater or equal to zero then we have an integer value,
+ // if new_exp is equal -1 then we have only one digit after the comma
+ // and after rounding it would be an integer value
+ if( !new_exp.IsSign() || new_exp == -1 )
+ return true;
+
+ if( new_man.size() >= TTMATH_UINT_HIGHEST_BIT || new_man.size() < 2 )
+ return true; // oops, the mantissa is too large for calculating (or too small) - we are not doing the base rounding
+
+ uint i = 0;
+ char_type digit;
+
+ if( new_exp >= -sint(new_man.size()) )
+ {
+ uint new_exp_abs = -new_exp.ToInt();
+ i = new_man.size() - new_exp_abs; // start from the first digit after the comma operator
+ }
+
+ if( Misc::CharToDigit(new_man[new_man.size()-1]) >= conv.base/2 )
+ {
+ if( new_exp < -sint(new_man.size()) )
+ {
+ // there are some zeroes after the comma operator
+ // (between the comma and the first digit from the mantissa)
+ // and the result value will never be an integer
+ return false;
+ }
+
+ digit = static_cast<char_type>( Misc::DigitToChar(conv.base-1) );
+ }
+ else
+ {
+ digit = '0';
+ }
+
+ for( ; i < new_man.size()-1 ; ++i)
+ if( new_man[i] != digit )
+ return false; // it will not be an integer
+
+ return true; // it will be integer after rounding
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ (when this is integer)
+
+ after floating point calculating the new mantissa can consist of some fraction
+ so if our value is integer we should check the new mantissa
+ (after the decimal point there should be only zeroes)
+
+ often this is a last digit different from zero
+ ToString_BaseRound would not get rid of it because the method make a test against
+ an integer value (ToString_RoundMantissaWouldBeInteger) and returns immediately
+ */
+ template<class string_type, class char_type>
+ void ToString_CheckMantissaInteger(string_type & new_man, const Int<exp+1> & new_exp) const
+ {
+ if( !new_exp.IsSign() )
+ return; // return if new_exp >= 0
+
+ uint i = 0;
+ uint man_size = new_man.size();
+
+ if( man_size >= TTMATH_UINT_HIGHEST_BIT )
+ return; // ops, the mantissa is too long
+
+ sint sman_size = -sint(man_size);
+
+ if( new_exp >= sman_size )
+ {
+ sint e = new_exp.ToInt();
+ e = -e;
+ // now e means how many last digits from the mantissa should be equal zero
+
+ i = man_size - uint(e);
+ }
+
+ for( ; i<man_size ; ++i)
+ new_man[i] = '0';
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+
+ this method is used for base!=2, base!=4, base!=8 and base!=16
+ we do the rounding when the value has fraction (is not an integer)
+ */
+ template<class string_type, class char_type>
+ uint ToString_BaseRound(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
+ {
+ // we must have minimum two characters
+ if( new_man.size() < 2 )
+ return 0;
+
+ // assert that there will not be an integer after rounding
+ if( ToString_RoundMantissaWouldBeInteger<string_type, char_type>(new_man, conv, new_exp) )
+ return 0;
+
+ typename string_type::size_type i = new_man.length() - 1;
+
+ // we're erasing the last character
+ uint digit = Misc::CharToDigit( new_man[i] );
+ new_man.erase(i, 1);
+ uint c = new_exp.AddOne();
+
+ // if the last character is greater or equal 'base/2'
+ // we are adding one into the new mantissa
+ if( digit >= conv.base / 2 )
+ ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
+
+ return c;
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+
+ this method addes one into the new mantissa
+ */
+ template<class string_type, class char_type>
+ void ToString_RoundMantissa_AddOneIntoMantissa(string_type & new_man, const Conv & conv) const
+ {
+ if( new_man.empty() )
+ return;
+
+ sint i = sint( new_man.length() ) - 1;
+ bool was_carry = true;
+
+ for( ; i>=0 && was_carry ; --i )
+ {
+ // we can have the comma as well because
+ // we're using this method later in ToString_CorrectDigitsAfterComma_Round()
+ // (we're only ignoring it)
+ if( new_man[i] == static_cast<char_type>(conv.comma) )
+ continue;
+
+ // we're adding one
+ uint digit = Misc::CharToDigit( new_man[i] ) + 1;
+
+ if( digit == conv.base )
+ digit = 0;
+ else
+ was_carry = false;
+
+ new_man[i] = static_cast<char_type>( Misc::DigitToChar(digit) );
+ }
+
+ if( i<0 && was_carry )
+ new_man.insert( new_man.begin() , '1' );
+ }
+
+
+
+ /*!
+ an auxiliary method for converting into the string
+
+ this method sets the comma operator and/or puts the exponent
+ into the string
+ */
+ template<class string_type, class char_type>
+ uint ToString_SetCommaAndExponent(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
+ {
+ uint carry = 0;
+
+ if( new_man.empty() )
+ return carry;
+
+ Int<exp+1> scientific_exp( new_exp );
+
+ // 'new_exp' depends on the 'new_man' which is stored like this e.g:
+ // 32342343234 (the comma is at the end)
+ // we'd like to show it in this way:
+ // 3.2342343234 (the 'scientific_exp' is connected with this example)
+
+ sint offset = sint( new_man.length() ) - 1;
+ carry += scientific_exp.Add( offset );
+ // there shouldn't have been a carry because we're using
+ // a greater type -- 'Int<exp+1>' instead of 'Int<exp>'
+
+ bool print_scientific = conv.scient;
+
+ if( !print_scientific )
+ {
+ if( scientific_exp > conv.scient_from || scientific_exp < -sint(conv.scient_from) )
+ print_scientific = true;
+ }
+
+ if( !print_scientific )
+ ToString_SetCommaAndExponent_Normal<string_type, char_type>(new_man, conv, new_exp);
+ else
+ // we're passing the 'scientific_exp' instead of 'new_exp' here
+ ToString_SetCommaAndExponent_Scientific<string_type, char_type>(new_man, conv, scientific_exp);
+
+ return (carry==0)? 0 : 1;
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_SetCommaAndExponent_Normal(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp ) const
+ {
+ if( !new_exp.IsSign() ) // it means: if( new_exp >= 0 )
+ ToString_SetCommaAndExponent_Normal_AddingZero<string_type, char_type>(new_man, new_exp);
+ else
+ ToString_SetCommaAndExponent_Normal_SetCommaInside<string_type, char_type>(new_man, conv, new_exp);
+
+
+ ToString_Group_man<string_type, char_type>(new_man, conv);
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_SetCommaAndExponent_Normal_AddingZero(string_type & new_man,
+ Int<exp+1> & new_exp) const
+ {
+ // we're adding zero characters at the end
+ // 'i' will be smaller than 'when_scientific' (or equal)
+ uint i = new_exp.ToInt();
+
+ if( new_man.length() + i > new_man.capacity() )
+ // about 6 characters more (we'll need it for the comma or something)
+ new_man.reserve( new_man.length() + i + 6 );
+
+ for( ; i>0 ; --i)
+ new_man += '0';
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_SetCommaAndExponent_Normal_SetCommaInside(
+ string_type & new_man,
+ const Conv & conv,
+ Int<exp+1> & new_exp ) const
+ {
+ // new_exp is < 0
+
+ sint new_man_len = sint(new_man.length()); // 'new_man_len' with a sign
+ sint e = -( new_exp.ToInt() ); // 'e' will be positive
+
+ if( new_exp > -new_man_len )
+ {
+ // we're setting the comma within the mantissa
+
+ sint index = new_man_len - e;
+ new_man.insert( new_man.begin() + index, static_cast<char_type>(conv.comma));
+ }
+ else
+ {
+ // we're adding zero characters before the mantissa
+
+ uint how_many = e - new_man_len;
+ string_type man_temp(how_many+1, '0');
+
+ man_temp.insert( man_temp.begin()+1, static_cast<char_type>(conv.comma));
+ new_man.insert(0, man_temp);
+ }
+
+ ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_SetCommaAndExponent_Scientific( string_type & new_man,
+ const Conv & conv,
+ Int<exp+1> & scientific_exp ) const
+ {
+ if( new_man.empty() )
+ return;
+
+ if( new_man.size() > 1 )
+ {
+ new_man.insert( new_man.begin()+1, static_cast<char_type>(conv.comma) );
+ ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
+ }
+
+ ToString_Group_man<string_type, char_type>(new_man, conv);
+
+ if( conv.base == 10 )
+ {
+ new_man += 'e';
+
+ if( !scientific_exp.IsSign() )
+ new_man += '+';
+ }
+ else
+ {
+ // the 10 here is meant as the base 'base'
+ // (no matter which 'base' we're using there'll always be 10 here)
+ Misc::AddString(new_man, "*10^");
+ }
+
+ string_type temp_exp;
+ scientific_exp.ToString( temp_exp, conv.base );
+
+ new_man += temp_exp;
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_Group_man(string_type & new_man, const Conv & conv) const
+ {
+ typedef typename string_type::size_type StrSize;
+
+ if( conv.group == 0 )
+ return;
+
+ // first we're looking for the comma operator
+ StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
+
+ if( index == string_type::npos )
+ index = new_man.size();
+
+ ToString_Group_man_before_comma<string_type, char_type>(new_man, conv, index);
+ ToString_Group_man_after_comma<string_type, char_type>(new_man, conv, index+1);
+ }
+
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_Group_man_before_comma( string_type & new_man, const Conv & conv,
+ typename string_type::size_type & index) const
+ {
+ typedef typename string_type::size_type StrSize;
+
+ uint group = 0;
+ StrSize i = index;
+ uint group_digits = conv.group_digits;
+
+ if( group_digits < 1 )
+ group_digits = 1;
+
+ // adding group characters before the comma operator
+ // i>0 because on the first position we don't put any additional grouping characters
+ for( ; i>0 ; --i, ++group)
+ {
+ if( group >= group_digits )
+ {
+ group = 0;
+ new_man.insert(i, 1, static_cast<char_type>(conv.group));
+ ++index;
+ }
+ }
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_Group_man_after_comma(string_type & new_man, const Conv & conv,
+ typename string_type::size_type index) const
+ {
+ uint group = 0;
+ uint group_digits = conv.group_digits;
+
+ if( group_digits < 1 )
+ group_digits = 1;
+
+ for( ; index<new_man.size() ; ++index, ++group)
+ {
+ if( group >= group_digits )
+ {
+ group = 0;
+ new_man.insert(index, 1, static_cast<char_type>(conv.group));
+ ++index;
+ }
+ }
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_CorrectDigitsAfterComma( string_type & new_man,
+ const Conv & conv ) const
+ {
+ if( conv.round >= 0 )
+ ToString_CorrectDigitsAfterComma_Round<string_type, char_type>(new_man, conv);
+
+ if( conv.trim_zeroes )
+ ToString_CorrectDigitsAfterComma_CutOffZeroCharacters<string_type, char_type>(new_man, conv);
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
+ string_type & new_man,
+ const Conv & conv) const
+ {
+ // minimum two characters
+ if( new_man.length() < 2 )
+ return;
+
+ // we're looking for the index of the last character which is not zero
+ uint i = uint( new_man.length() ) - 1;
+ for( ; i>0 && new_man[i]=='0' ; --i );
+
+ // if there is another character than zero at the end
+ // we're finishing
+ if( i == new_man.length() - 1 )
+ return;
+
+ // we must have a comma
+ // (the comma can be removed by ToString_CorrectDigitsAfterComma_Round
+ // which is called before)
+ if( new_man.find_last_of(static_cast<char_type>(conv.comma), i) == string_type::npos )
+ return;
+
+ // if directly before the first zero is the comma operator
+ // we're cutting it as well
+ if( i>0 && new_man[i]==static_cast<char_type>(conv.comma) )
+ --i;
+
+ new_man.erase(i+1, new_man.length()-i-1);
+ }
+
+
+ /*!
+ an auxiliary method for converting into the string
+ */
+ template<class string_type, class char_type>
+ void ToString_CorrectDigitsAfterComma_Round(
+ string_type & new_man,
+ const Conv & conv ) const
+ {
+ typedef typename string_type::size_type StrSize;
+
+ // first we're looking for the comma operator
+ StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
+
+ if( index == string_type::npos )
+ // nothing was found (actually there can't be this situation)
+ return;
+
+ // we're calculating how many digits there are at the end (after the comma)
+ // 'after_comma' will be greater than zero because at the end
+ // we have at least one digit
+ StrSize after_comma = new_man.length() - index - 1;
+
+ // if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
+ // we don't have anything for cutting
+ if( static_cast<StrSize>(conv.round) >= after_comma )
+ return;
+
+ uint last_digit = Misc::CharToDigit( new_man[ index + conv.round + 1 ], conv.base );
+
+ // we're cutting the rest of the string
+ new_man.erase(index + conv.round + 1, after_comma - conv.round);
+
+ if( conv.round == 0 )
+ {
+ // we're cutting the comma operator as well
+ // (it's not needed now because we've cut the whole rest after the comma)
+ new_man.erase(index, 1);
+ }
+
+ if( last_digit >= conv.base / 2 )
+ // we must round here
+ ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
+ }
+
+
+
+public:
+
+ /*!
+ a method for converting a string into its value
+
+ it returns 1 if the value is too big -- we cannot pass it into the range
+ of our class Big<exp,man> (or if the base is incorrect)
+
+ that means only digits before the comma operator can make this value too big,
+ all digits after the comma we can ignore
+
+ 'source' - pointer to the string for parsing
+
+ if 'after_source' is set that when this method finishes
+ it sets the pointer to the new first character after parsed value
+
+ 'value_read' - if the pointer is provided that means the value_read will be true
+ only when a value has been actually read, there can be situation where only such
+ a string '-' or '+' will be parsed -- 'after_source' will be different from 'source' but
+ no value has been read (there are no digits)
+ on other words if 'value_read' is true -- there is at least one digit in the string
+ */
+ uint FromString(const char * source, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
+ {
+ Conv conv;
+ conv.base = base;
+
+ return FromStringBase(source, conv, after_source, value_read);
+ }
+
+
+ /*!
+ a method for converting a string into its value
+ */
+ uint FromString(const char * source, const Conv & conv, const char ** after_source = 0, bool * value_read = 0)
+ {
+ return FromStringBase(source, conv, after_source, value_read);
+ }
+
+
+ /*!
+ a method for converting a string into its value
+ */
+ uint FromString(const std::string & string, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
+ {
+ return FromString(string.c_str(), base, after_source, value_read);
+ }
+
+
+ /*!
+ a method for converting a string into its value
+ */
+ uint FromString(const std::string & string, const Conv & conv, const char ** after_source = 0, bool * value_read = 0)
+ {
+ return FromString(string.c_str(), conv, after_source, value_read);
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ a method for converting a string into its value
+ */
+ uint FromString(const wchar_t * source, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+ {
+ Conv conv;
+ conv.base = base;
+
+ return FromStringBase(source, conv, after_source, value_read);
+ }
+
+
+ /*!
+ a method for converting a string into its value
+ */
+ uint FromString(const wchar_t * source, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
+ {
+ return FromStringBase(source, conv, after_source, value_read);
+ }
+
+
+ /*!
+ a method for converting a string into its value
+ */
+ uint FromString(const std::wstring & string, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+ {
+ return FromString(string.c_str(), base, after_source, value_read);
+ }
+
+
+ /*!
+ a method for converting a string into its value
+ */
+ uint FromString(const std::wstring & string, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
+ {
+ return FromString(string.c_str(), conv, after_source, value_read);
+ }
+
+#endif
+
+
+private:
+
+
+ /*!
+ an auxiliary method for converting from a string
+ */
+ template<class char_type>
+ uint FromStringBase(const char_type * source, const Conv & conv, const char_type ** after_source = 0, bool * value_read = 0)
+ {
+ bool is_sign;
+ bool value_read_temp = false;
+
+ if( conv.base<2 || conv.base>16 )
+ {
+ SetNan();
+
+ if( after_source )
+ *after_source = source;
+
+ if( value_read )
+ *value_read = value_read_temp;
+
+ return 1;
+ }
+
+ SetZero();
+ FromString_TestSign( source, is_sign );
+
+ uint c = FromString_ReadPartBeforeComma( source, conv, value_read_temp );
+
+ if( FromString_TestCommaOperator(source, conv) )
+ c += FromString_ReadPartAfterComma( source, conv, value_read_temp );
+
+ if( value_read_temp && conv.base == 10 )
+ c += FromString_ReadScientificIfExists( source );
+
+ if( is_sign && !IsZero() )
+ ChangeSign();
+
+ if( after_source )
+ *after_source = source;
+
+ if( value_read )
+ *value_read = value_read_temp;
+
+ return CheckCarry(c);
+ }
+
+
+ /*!
+ we're testing whether the value is with the sign
+
+ (this method is used from 'FromString_ReadPartScientific' too)
+ */
+ template<class char_type>
+ void FromString_TestSign( const char_type * & source, bool & is_sign )
+ {
+ Misc::SkipWhiteCharacters(source);
+
+ is_sign = false;
+
+ if( *source == '-' )
+ {
+ is_sign = true;
+ ++source;
+ }
+ else
+ if( *source == '+' )
+ {
+ ++source;
+ }
+ }
+
+
+ /*!
+ we're testing whether there's a comma operator
+ */
+ template<class char_type>
+ bool FromString_TestCommaOperator(const char_type * & source, const Conv & conv)
+ {
+ if( (*source == static_cast<char_type>(conv.comma)) ||
+ (*source == static_cast<char_type>(conv.comma2) && conv.comma2 != 0 ) )
+ {
+ ++source;
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /*!
+ this method reads the first part of a string
+ (before the comma operator)
+ */
+ template<class char_type>
+ uint FromString_ReadPartBeforeComma( const char_type * & source, const Conv & conv, bool & value_read )
+ {
+ sint character;
+ Big<exp, man> temp;
+ Big<exp, man> base_( conv.base );
+
+ Misc::SkipWhiteCharacters( source );
+
+ for( ; true ; ++source )
+ {
+ if( conv.group!=0 && *source==static_cast<char>(conv.group) )
+ continue;
+
+ character = Misc::CharToDigit(*source, conv.base);
+
+ if( character == -1 )
+ break;
+
+ value_read = true;
+ temp = character;
+
+ if( Mul(base_) )
+ return 1;
+
+ if( Add(temp) )
+ return 1;
+ }
+
+ return 0;
+ }
+
+
+ /*!
+ this method reads the second part of a string
+ (after the comma operator)
+ */
+ template<class char_type>
+ uint FromString_ReadPartAfterComma( const char_type * & source, const Conv & conv, bool & value_read )
+ {
+ sint character;
+ uint c = 0, index = 1;
+ Big<exp, man> sum, part, power, old_value, base_( conv.base );
+
+ // we don't remove any white characters here
+
+ // this is only to avoid getting a warning about an uninitialized object 'old_value' which GCC reports
+ // (in fact we will initialize it later when the condition 'testing' is fulfilled)
+ old_value.SetZero();
+
+ power.SetOne();
+ sum.SetZero();
+
+ for( ; true ; ++source, ++index )
+ {
+ if( conv.group!=0 && *source==static_cast<char>(conv.group) )
+ continue;
+
+ character = Misc::CharToDigit(*source, conv.base);
+
+ if( character == -1 )
+ break;
+
+ value_read = true;
+
+ part = character;
+
+ if( power.Mul( base_ ) )
+ // there's no sens to add the next parts, but we can't report this
+ // as an error (this is only inaccuracy)
+ break;
+
+ if( part.Div( power ) )
+ break;
+
+ // every 5 iteration we make a test whether the value will be changed or not
+ // (character must be different from zero to this test)
+ bool testing = (character != 0 && (index % 5) == 0);
+
+ if( testing )
+ old_value = sum;
+
+ // there actually shouldn't be a carry here
+ c += sum.Add( part );
+
+ if( testing && old_value == sum )
+ // after adding 'part' the value has not been changed
+ // there's no sense to add any next parts
+ break;
+ }
+
+ // we could break the parsing somewhere in the middle of the string,
+ // but the result (value) still can be good
+ // we should set a correct value of 'source' now
+ for( ; Misc::CharToDigit(*source, conv.base) != -1 ; ++source );
+
+ c += Add(sum);
+
+ return (c==0)? 0 : 1;
+ }
+
+
+ /*!
+ this method checks whether there is a scientific part: [e|E][-|+]value
+
+ it is called when the base is 10 and some digits were read before
+ */
+ template<class char_type>
+ uint FromString_ReadScientificIfExists(const char_type * & source)
+ {
+ uint c = 0;
+
+ bool scientific_read = false;
+ const char_type * before_scientific = source;
+
+ if( FromString_TestScientific(source) )
+ c += FromString_ReadPartScientific( source, scientific_read );
+
+ if( !scientific_read )
+ source = before_scientific;
+
+ return (c==0)? 0 : 1;
+ }
+
+
+
+ /*!
+ we're testing whether is there the character 'e'
+
+ this character is only allowed when we're using the base equals 10
+ */
+ template<class char_type>
+ bool FromString_TestScientific(const char_type * & source)
+ {
+ Misc::SkipWhiteCharacters(source);
+
+ if( *source=='e' || *source=='E' )
+ {
+ ++source;
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /*!
+ this method reads the exponent (after 'e' character) when there's a scientific
+ format of value and only when we're using the base equals 10
+ */
+ template<class char_type>
+ uint FromString_ReadPartScientific( const char_type * & source, bool & scientific_read )
+ {
+ uint c = 0;
+ Big<exp, man> new_exponent, temp;
+ bool was_sign = false;
+
+ FromString_TestSign( source, was_sign );
+ c += FromString_ReadPartScientific_ReadExponent( source, new_exponent, scientific_read );
+
+ if( scientific_read )
+ {
+ if( was_sign )
+ new_exponent.ChangeSign();
+
+ temp = 10;
+ c += temp.Pow( new_exponent );
+ c += Mul(temp);
+ }
+
+ return (c==0)? 0 : 1;
+ }
+
+
+ /*!
+ this method reads the value of the extra exponent when scientific format is used
+ (only when base == 10)
+ */
+ template<class char_type>
+ uint FromString_ReadPartScientific_ReadExponent( const char_type * & source, Big<exp, man> & new_exponent, bool & scientific_read )
+ {
+ sint character;
+ Big<exp, man> base, temp;
+
+ Misc::SkipWhiteCharacters(source);
+
+ new_exponent.SetZero();
+ base = 10;
+
+ for( ; (character=Misc::CharToDigit(*source, 10)) != -1 ; ++source )
+ {
+ scientific_read = true;
+
+ temp = character;
+
+ if( new_exponent.Mul(base) )
+ return 1;
+
+ if( new_exponent.Add(temp) )
+ return 1;
+ }
+
+ return 0;
+ }
+
+
+public:
+
+
+ /*!
+ a constructor for converting a string into this class
+ */
+ Big(const char * string)
+ {
+ FromString( string );
+ }
+
+
+ /*!
+ a constructor for converting a string into this class
+ */
+ Big(const std::string & string)
+ {
+ FromString( string.c_str() );
+ }
+
+
+ /*!
+ an operator= for converting a string into its value
+ */
+ Big<exp, man> & operator=(const char * string)
+ {
+ FromString( string );
+
+ return *this;
+ }
+
+
+ /*!
+ an operator= for converting a string into its value
+ */
+ Big<exp, man> & operator=(const std::string & string)
+ {
+ FromString( string.c_str() );
+
+ return *this;
+ }
+
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ a constructor for converting a string into this class
+ */
+ Big(const wchar_t * string)
+ {
+ FromString( string );
+ }
+
+
+ /*!
+ a constructor for converting a string into this class
+ */
+ Big(const std::wstring & string)
+ {
+ FromString( string.c_str() );
+ }
+
+
+ /*!
+ an operator= for converting a string into its value
+ */
+ Big<exp, man> & operator=(const wchar_t * string)
+ {
+ FromString( string );
+
+ return *this;
+ }
+
+
+ /*!
+ an operator= for converting a string into its value
+ */
+ Big<exp, man> & operator=(const std::wstring & string)
+ {
+ FromString( string.c_str() );
+
+ return *this;
+ }
+
+
+#endif
+
+
+
+ /*!
+ *
+ * methods for comparing
+ *
+ */
+
+
+ /*!
+ this method performs the formula 'abs(this) < abs(ss2)'
+ and returns the result
+
+ (in other words it treats 'this' and 'ss2' as values without a sign)
+ we don't check the NaN flag
+ */
+ bool SmallerWithoutSignThan(const Big<exp,man> & ss2) const
+ {
+ if( IsZero() )
+ {
+ if( ss2.IsZero() )
+ // we've got two zeroes
+ return false;
+ else
+ // this==0 and ss2!=0
+ return true;
+ }
+
+ if( ss2.IsZero() )
+ // this!=0 and ss2==0
+ return false;
+
+ // we're using the fact that all bits in mantissa are pushed
+ // into the left side -- Standardizing()
+ if( exponent == ss2.exponent )
+ return mantissa < ss2.mantissa;
+
+ return exponent < ss2.exponent;
+ }
+
+
+ /*!
+ this method performs the formula 'abs(this) > abs(ss2)'
+ and returns the result
+
+ (in other words it treats 'this' and 'ss2' as values without a sign)
+ we don't check the NaN flag
+ */
+ bool GreaterWithoutSignThan(const Big<exp,man> & ss2) const
+ {
+ if( IsZero() )
+ {
+ if( ss2.IsZero() )
+ // we've got two zeroes
+ return false;
+ else
+ // this==0 and ss2!=0
+ return false;
+ }
+
+ if( ss2.IsZero() )
+ // this!=0 and ss2==0
+ return true;
+
+ // we're using the fact that all bits in mantissa are pushed
+ // into the left side -- Standardizing()
+ if( exponent == ss2.exponent )
+ return mantissa > ss2.mantissa;
+
+ return exponent > ss2.exponent;
+ }
+
+
+ /*!
+ this method performs the formula 'abs(this) == abs(ss2)'
+ and returns the result
+
+ (in other words it treats 'this' and 'ss2' as values without a sign)
+ we don't check the NaN flag
+ */
+ bool EqualWithoutSign(const Big<exp,man> & ss2) const
+ {
+ if( IsZero() )
+ {
+ if( ss2.IsZero() )
+ // we've got two zeroes
+ return true;
+ else
+ // this==0 and ss2!=0
+ return false;
+ }
+
+ if( ss2.IsZero() )
+ // this!=0 and ss2==0
+ return false;
+
+ if( exponent==ss2.exponent && mantissa==ss2.mantissa )
+ return true;
+
+ return false;
+ }
+
+
+ bool operator<(const Big<exp,man> & ss2) const
+ {
+ if( IsSign() && !ss2.IsSign() )
+ // this<0 and ss2>=0
+ return true;
+
+ if( !IsSign() && ss2.IsSign() )
+ // this>=0 and ss2<0
+ return false;
+
+ // both signs are the same
+
+ if( IsSign() )
+ return ss2.SmallerWithoutSignThan( *this );
+
+ return SmallerWithoutSignThan( ss2 );
+ }
+
+
+ bool operator==(const Big<exp,man> & ss2) const
+ {
+ if( IsSign() != ss2.IsSign() )
+ return false;
+
+ return EqualWithoutSign( ss2 );
+ }
+
+
+ bool operator>(const Big<exp,man> & ss2) const
+ {
+ if( IsSign() && !ss2.IsSign() )
+ // this<0 and ss2>=0
+ return false;
+
+ if( !IsSign() && ss2.IsSign() )
+ // this>=0 and ss2<0
+ return true;
+
+ // both signs are the same
+
+ if( IsSign() )
+ return ss2.GreaterWithoutSignThan( *this );
+
+ return GreaterWithoutSignThan( ss2 );
+ }
+
+
+ bool operator>=(const Big<exp,man> & ss2) const
+ {
+ return !operator<( ss2 );
+ }
+
+
+ bool operator<=(const Big<exp,man> & ss2) const
+ {
+ return !operator>( ss2 );
+ }
+
+
+ bool operator!=(const Big<exp,man> & ss2) const
+ {
+ return !operator==(ss2);
+ }
+
+
+
+
+
+ /*!
+ *
+ * standard mathematical operators
+ *
+ */
+
+
+ /*!
+ an operator for changing the sign
+
+ this method is not changing 'this' but the changed value is returned
+ */
+ Big<exp,man> operator-() const
+ {
+ Big<exp,man> temp(*this);
+
+ temp.ChangeSign();
+
+ return temp;
+ }
+
+
+ Big<exp,man> operator-(const Big<exp,man> & ss2) const
+ {
+ Big<exp,man> temp(*this);
+
+ temp.Sub(ss2);
+
+ return temp;
+ }
+
+ Big<exp,man> & operator-=(const Big<exp,man> & ss2)
+ {
+ Sub(ss2);
+
+ return *this;
+ }
+
+
+ Big<exp,man> operator+(const Big<exp,man> & ss2) const
+ {
+ Big<exp,man> temp(*this);
+
+ temp.Add(ss2);
+
+ return temp;
+ }
+
+
+ Big<exp,man> & operator+=(const Big<exp,man> & ss2)
+ {
+ Add(ss2);
+
+ return *this;
+ }
+
+
+ Big<exp,man> operator*(const Big<exp,man> & ss2) const
+ {
+ Big<exp,man> temp(*this);
+
+ temp.Mul(ss2);
+
+ return temp;
+ }
+
+
+ Big<exp,man> & operator*=(const Big<exp,man> & ss2)
+ {
+ Mul(ss2);
+
+ return *this;
+ }
+
+
+ Big<exp,man> operator/(const Big<exp,man> & ss2) const
+ {
+ Big<exp,man> temp(*this);
+
+ temp.Div(ss2);
+
+ return temp;
+ }
+
+
+ Big<exp,man> & operator/=(const Big<exp,man> & ss2)
+ {
+ Div(ss2);
+
+ return *this;
+ }
+
+
+ /*!
+ Prefix operator e.g ++variable
+ */
+ Big<exp,man> & operator++()
+ {
+ AddOne();
+
+ return *this;
+ }
+
+
+ /*!
+ Postfix operator e.g variable++
+ */
+ Big<exp,man> operator++(int)
+ {
+ Big<exp,man> temp( *this );
+
+ AddOne();
+
+ return temp;
+ }
+
+
+ Big<exp,man> & operator--()
+ {
+ SubOne();
+
+ return *this;
+ }
+
+
+ Big<exp,man> operator--(int)
+ {
+ Big<exp,man> temp( *this );
+
+ SubOne();
+
+ return temp;
+ }
+
+
+
+ /*!
+ *
+ * bitwise operators
+ * (we do not define bitwise not)
+ */
+
+
+ Big<exp,man> operator&(const Big<exp,man> & p2) const
+ {
+ Big<exp,man> temp( *this );
+
+ temp.BitAnd(p2);
+
+ return temp;
+ }
+
+
+ Big<exp,man> & operator&=(const Big<exp,man> & p2)
+ {
+ BitAnd(p2);
+
+ return *this;
+ }
+
+
+ Big<exp,man> operator|(const Big<exp,man> & p2) const
+ {
+ Big<exp,man> temp( *this );
+
+ temp.BitOr(p2);
+
+ return temp;
+ }
+
+
+ Big<exp,man> & operator|=(const Big<exp,man> & p2)
+ {
+ BitOr(p2);
+
+ return *this;
+ }
+
+
+ Big<exp,man> operator^(const Big<exp,man> & p2) const
+ {
+ Big<exp,man> temp( *this );
+
+ temp.BitXor(p2);
+
+ return temp;
+ }
+
+
+ Big<exp,man> & operator^=(const Big<exp,man> & p2)
+ {
+ BitXor(p2);
+
+ return *this;
+ }
+
+
+
+
+
+
+ /*!
+ this method makes an integer value by skipping any fractions
+
+ for example:
+ 10.7 will be 10
+ 12.1 -- 12
+ -20.2 -- 20
+ -20.9 -- 20
+ -0.7 -- 0
+ 0.8 -- 0
+ */
+ void SkipFraction()
+ {
+ if( IsNan() || IsZero() )
+ return;
+
+ if( !exponent.IsSign() )
+ // exponent >=0 -- the value don't have any fractions
+ return;
+
+ if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
+ {
+ // the value is from (-1,1), we return zero
+ SetZero();
+ return;
+ }
+
+ // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
+ sint e = exponent.ToInt();
+
+ mantissa.ClearFirstBits( -e );
+
+ // we don't have to standardize 'Standardizing()' the value because
+ // there's at least one bit in the mantissa
+ // (the highest bit which we didn't touch)
+ }
+
+
+ /*!
+ this method remains only a fraction from the value
+
+ for example:
+ 30.56 will be 0.56
+ -12.67 -- -0.67
+ */
+ void RemainFraction()
+ {
+ if( IsNan() || IsZero() )
+ return;
+
+ if( !exponent.IsSign() )
+ {
+ // exponent >= 0 -- the value doesn't have any fractions
+ // we return zero
+ SetZero();
+ return;
+ }
+
+ if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
+ {
+ // the value is from (-1,1)
+ // we don't make anything with the value
+ return;
+ }
+
+ // e will be from (-man*TTMATH_BITS_PER_UINT, 0)
+ sint e = exponent.ToInt();
+
+ sint how_many_bits_leave = sint(man*TTMATH_BITS_PER_UINT) + e; // there'll be a subtraction -- e is negative
+ mantissa.Rcl( how_many_bits_leave, 0);
+
+ // there'll not be a carry because the exponent is too small
+ exponent.Sub( how_many_bits_leave );
+
+ // we must call Standardizing() here
+ Standardizing();
+ }
+
+
+
+ /*!
+ this method returns true if the value is integer
+ (there is no a fraction)
+
+ (we don't check nan)
+ */
+ bool IsInteger() const
+ {
+ if( IsZero() )
+ return true;
+
+ if( !exponent.IsSign() )
+ // exponent >=0 -- the value don't have any fractions
+ return true;
+
+ if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
+ // the value is from (-1,1)
+ return false;
+
+ // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
+ sint e = exponent.ToInt();
+ e = -e; // e means how many bits we must check
+
+ uint len = e / TTMATH_BITS_PER_UINT;
+ uint rest = e % TTMATH_BITS_PER_UINT;
+ uint i = 0;
+
+ for( ; i<len ; ++i )
+ if( mantissa.table[i] != 0 )
+ return false;
+
+ if( rest > 0 )
+ {
+ uint rest_mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
+ if( (mantissa.table[i] & rest_mask) != 0 )
+ return false;
+ }
+
+ return true;
+ }
+
+
+ /*!
+ this method rounds to the nearest integer value
+ (it returns a carry if it was)
+
+ for example:
+ 2.3 = 2
+ 2.8 = 3
+
+ -2.3 = -2
+ -2.8 = 3
+ */
+ uint Round()
+ {
+ Big<exp,man> half;
+ uint c;
+
+ if( IsNan() )
+ return 1;
+
+ if( IsZero() )
+ return 0;
+
+ half.Set05();
+
+ if( IsSign() )
+ {
+ // 'this' is < 0
+ c = Sub( half );
+ }
+ else
+ {
+ // 'this' is > 0
+ c = Add( half );
+ }
+
+ SkipFraction();
+
+ return CheckCarry(c);
+ }
+
+
+
+ /*!
+ *
+ * input/output operators for standard streams
+ *
+ */
+
+private:
+
+ /*!
+ an auxiliary method for outputing to standard streams
+ */
+ template<class ostream_type, class string_type>
+ static ostream_type & OutputToStream(ostream_type & s, const Big<exp,man> & l)
+ {
+ string_type ss;
+
+ l.ToString(ss);
+ s << ss;
+
+ return s;
+ }
+
+
+public:
+
+
+ /*!
+ output to standard streams
+ */
+ friend std::ostream & operator<<(std::ostream & s, const Big<exp,man> & l)
+ {
+ return OutputToStream<std::ostream, std::string>(s, l);
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ output to standard streams
+ */
+ friend std::wostream & operator<<(std::wostream & s, const Big<exp,man> & l)
+ {
+ return OutputToStream<std::wostream, std::wstring>(s, l);
+ }
+
+#endif
+
+
+
+private:
+
+ /*!
+ an auxiliary method for converting from a string
+ */
+ template<class istream_type, class string_type, class char_type>
+ static istream_type & InputFromStream(istream_type & s, Big<exp,man> & l)
+ {
+ string_type ss;
+
+ // char or wchar_t for operator>>
+ char_type z, old_z;
+ bool was_comma = false;
+ bool was_e = false;
+
+
+ // operator>> omits white characters if they're set for ommiting
+ s >> z;
+
+ if( z=='-' || z=='+' )
+ {
+ ss += z;
+ s >> z; // we're reading a next character (white characters can be ommited)
+ }
+
+ old_z = 0;
+
+ // we're reading only digits (base=10) and only one comma operator
+ for( ; s.good() ; z=static_cast<char_type>(s.get()) )
+ {
+ if( z=='.' || z==',' )
+ {
+ if( was_comma || was_e )
+ // second comma operator or comma operator after 'e' character
+ break;
+
+ was_comma = true;
+ }
+ else
+ if( z == 'e' || z == 'E' )
+ {
+ if( was_e )
+ // second 'e' character
+ break;
+
+ was_e = true;
+ }
+ else
+ if( z == '+' || z == '-' )
+ {
+ if( old_z != 'e' && old_z != 'E' )
+ // '+' or '-' is allowed only after 'e' character
+ break;
+ }
+ else
+ if( Misc::CharToDigit(z, 10) < 0 )
+ break;
+
+
+ ss += z;
+ old_z = z;
+ }
+
+ // we're leaving the last read character
+ // (it's not belonging to the value)
+ s.unget();
+
+ l.FromString( ss );
+
+ return s;
+ }
+
+
+
+public:
+
+ /*!
+ input from standard streams
+ */
+ friend std::istream & operator>>(std::istream & s, Big<exp,man> & l)
+ {
+ return InputFromStream<std::istream, std::string, char>(s, l);
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ input from standard streams
+ */
+ friend std::wistream & operator>>(std::wistream & s, Big<exp,man> & l)
+ {
+ return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
+ }
+
+#endif
+
+};
+
+
+} // namespace
+
+#endif
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathint.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathint.h
new file mode 100644
index 0000000..ad306f0
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathint.h
@@ -0,0 +1,1922 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2011, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathint
+#define headerfilettmathint
+
+/*!
+ \file ttmathint.h
+ \brief template class Int<uint>
+*/
+
+#include "ttmathuint.h"
+
+namespace ttmath
+{
+
+
+/*!
+ \brief Int implements a big integer value with a sign
+
+ value_size - how many bytes specify our value
+ on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
+ on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
+ value_size = 1,2,3,4,5,6....
+*/
+template<uint value_size>
+class Int : public UInt<value_size>
+{
+public:
+
+ /*!
+ this method sets the max value which this class can hold
+ (all bits will be one besides the last one)
+ */
+ void SetMax()
+ {
+ UInt<value_size>::SetMax();
+ UInt<value_size>::table[value_size-1] = ~ TTMATH_UINT_HIGHEST_BIT;
+ }
+
+
+ /*!
+ this method sets the min value which this class can hold
+ (all bits will be zero besides the last one which is one)
+ */
+ void SetMin()
+ {
+ UInt<value_size>::SetZero();
+ UInt<value_size>::table[value_size-1] = TTMATH_UINT_HIGHEST_BIT;
+ }
+
+
+ /*!
+ this method sets -1 as the value
+ (-1 is equal the max value in an unsigned type)
+ */
+ void SetSignOne()
+ {
+ UInt<value_size>::SetMax();
+ }
+
+
+ /*!
+ we change the sign of the value
+
+ if it isn't possible to change the sign this method returns 1
+ else return 0 and changing the sign
+ */
+ uint ChangeSign()
+ {
+ /*
+ if the value is equal that one which has been returned from SetMin
+ (only the highest bit is set) that means we can't change sign
+ because the value is too big (bigger about one)
+
+ e.g. when value_size = 1 and value is -2147483648 we can't change it to the
+ 2147483648 because the max value which can be held is 2147483647
+
+ we don't change the value and we're using this fact somewhere in some methods
+ (if we look on our value without the sign we get the correct value
+ eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
+ */
+ if( UInt<value_size>::IsOnlyTheHighestBitSet() )
+ return 1;
+
+ UInt<value_size> temp(*this);
+ UInt<value_size>::SetZero();
+ UInt<value_size>::Sub(temp);
+
+ return 0;
+ }
+
+
+
+ /*!
+ this method sets the sign
+
+ e.g. 1 -> -1
+ -2 -> -2
+
+ from a positive value we make a negative value,
+ if the value is negative we do nothing
+ */
+ void SetSign()
+ {
+ if( IsSign() )
+ return;
+
+ ChangeSign();
+ }
+
+
+
+ /*!
+ this method returns true if there's the sign
+
+ (the highest bit will be converted to the bool)
+ */
+ bool IsSign() const
+ {
+ return UInt<value_size>::IsTheHighestBitSet();
+ }
+
+
+
+ /*!
+ it sets an absolute value
+
+ it can return carry (1) (look on ChangeSign() for details)
+ */
+ uint Abs()
+ {
+ if( !IsSign() )
+ return 0;
+
+ return ChangeSign();
+ }
+
+
+
+
+ /*!
+ *
+ * basic mathematic functions
+ *
+ */
+
+private:
+
+ uint CorrectCarryAfterAdding(bool p1_is_sign, bool p2_is_sign)
+ {
+ if( !p1_is_sign && !p2_is_sign )
+ {
+ if( UInt<value_size>::IsTheHighestBitSet() )
+ return 1;
+ }
+
+ if( p1_is_sign && p2_is_sign )
+ {
+ if( ! UInt<value_size>::IsTheHighestBitSet() )
+ return 1;
+ }
+
+ return 0;
+ }
+
+
+public:
+
+ /*!
+ this method adds two value with a sign and returns a carry
+
+ we're using methods from the base class because values are stored with U2
+ we must only make the carry correction
+
+ this = p1(=this) + p2
+
+ when p1>=0 i p2>=0 carry is set when the highest bit of value is set
+ when p1<0 i p2<0 carry is set when the highest bit of value is clear
+ when p1>=0 i p2<0 carry will never be set
+ when p1<0 i p2>=0 carry will never be set
+ */
+ uint Add(const Int<value_size> & ss2)
+ {
+ bool p1_is_sign = IsSign();
+ bool p2_is_sign = ss2.IsSign();
+
+ UInt<value_size>::Add(ss2);
+
+ return CorrectCarryAfterAdding(p1_is_sign, p2_is_sign);
+ }
+
+
+ /*!
+ this method adds one *unsigned* word (at a specific position)
+ and returns a carry (if it was)
+
+ look at a description in UInt<>::AddInt(...)
+ */
+ uint AddInt(uint value, uint index = 0)
+ {
+ bool p1_is_sign = IsSign();
+
+ UInt<value_size>::AddInt(value, index);
+
+ return CorrectCarryAfterAdding(p1_is_sign, false);
+ }
+
+
+ /*!
+ this method adds two *unsigned* words to the existing value
+ and these words begin on the 'index' position
+
+ index should be equal or smaller than value_size-2 (index <= value_size-2)
+ x1 - lower word, x2 - higher word
+
+ look at a description in UInt<>::AddTwoInts(...)
+ */
+ uint AddTwoInts(uint x2, uint x1, uint index)
+ {
+ bool p1_is_sign = IsSign();
+
+ UInt<value_size>::AddTwoInts(x2, x1, index);
+
+ return CorrectCarryAfterAdding(p1_is_sign, false);
+ }
+
+private:
+
+ uint CorrectCarryAfterSubtracting(bool p1_is_sign, bool p2_is_sign)
+ {
+ if( !p1_is_sign && p2_is_sign )
+ {
+ if( UInt<value_size>::IsTheHighestBitSet() )
+ return 1;
+ }
+
+ if( p1_is_sign && !p2_is_sign )
+ {
+ if( ! UInt<value_size>::IsTheHighestBitSet() )
+ return 1;
+ }
+
+ return 0;
+ }
+
+public:
+
+ /*!
+ this method subtracts two values with a sign
+
+ we don't use the previous Add because the method ChangeSign can
+ sometimes return carry
+
+ this = p1(=this) - p2
+
+ when p1>=0 i p2>=0 carry will never be set
+ when p1<0 i p2<0 carry will never be set
+ when p1>=0 i p2<0 carry is set when the highest bit of value is set
+ when p1<0 i p2>=0 carry is set when the highest bit of value is clear
+ */
+ uint Sub(const Int<value_size> & ss2)
+ {
+ bool p1_is_sign = IsSign();
+ bool p2_is_sign = ss2.IsSign();
+
+ UInt<value_size>::Sub(ss2);
+
+ return CorrectCarryAfterSubtracting(p1_is_sign, p2_is_sign);
+ }
+
+
+ /*!
+ this method subtracts one *unsigned* word (at a specific position)
+ and returns a carry (if it was)
+ */
+ uint SubInt(uint value, uint index = 0)
+ {
+ bool p1_is_sign = IsSign();
+
+ UInt<value_size>::SubInt(value, index);
+
+ return CorrectCarryAfterSubtracting(p1_is_sign, false);
+ }
+
+
+ /*!
+ this method adds one to the value and returns carry
+ */
+ uint AddOne()
+ {
+ bool p1_is_sign = IsSign();
+
+ UInt<value_size>::AddOne();
+
+ return CorrectCarryAfterAdding(p1_is_sign, false);
+ }
+
+
+ /*!
+ this method subtracts one from the value and returns carry
+ */
+ uint SubOne()
+ {
+ bool p1_is_sign = IsSign();
+
+ UInt<value_size>::SubOne();
+
+ return CorrectCarryAfterSubtracting(p1_is_sign, false);
+ }
+
+
+private:
+
+
+ uint CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign)
+ {
+ /*
+ we have to examine the sign of the result now
+ but if the result is with the sign then:
+ 1. if the signs were the same that means the result is too big
+ (the result must be without a sign)
+ 2. if the signs were different that means if the result
+ is different from that one which has been returned from SetMin()
+ that is carry (result too big) but if the result is equal SetMin()
+ there'll be ok (and the next SetSign will has no effect because
+ the value is actually negative -- look at description of that case
+ in ChangeSign())
+ */
+ if( IsSign() )
+ {
+ if( ss1_is_sign != ss2_is_sign )
+ {
+ /*
+ there can be one case where signs are different and
+ the result will be equal the value from SetMin() (only the highest bit is set)
+ (this situation is ok)
+ */
+ if( !UInt<value_size>::IsOnlyTheHighestBitSet() )
+ return 1;
+ }
+ else
+ {
+ // signs were the same
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+
+public:
+
+
+ /*!
+ multiplication: this = this * ss2
+
+ it can return a carry
+ */
+ uint MulInt(sint ss2)
+ {
+ bool ss1_is_sign, ss2_is_sign;
+ uint c;
+
+ ss1_is_sign = IsSign();
+
+ /*
+ we don't have to check the carry from Abs (values will be correct
+ because next we're using the method MulInt from the base class UInt
+ which is without a sign)
+ */
+ Abs();
+
+ if( ss2 < 0 )
+ {
+ ss2 = -ss2;
+ ss2_is_sign = true;
+ }
+ else
+ {
+ ss2_is_sign = false;
+ }
+
+ c = UInt<value_size>::MulInt((uint)ss2);
+ c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
+
+ if( ss1_is_sign != ss2_is_sign )
+ SetSign();
+
+ return c;
+ }
+
+
+
+ /*!
+ multiplication this = this * ss2
+
+ it returns carry if the result is too big
+ (we're using the method from the base class but we have to make
+ one correction in account of signs)
+ */
+ uint Mul(Int<value_size> ss2)
+ {
+ bool ss1_is_sign, ss2_is_sign;
+ uint c;
+
+ ss1_is_sign = IsSign();
+ ss2_is_sign = ss2.IsSign();
+
+ /*
+ we don't have to check the carry from Abs (values will be correct
+ because next we're using the method Mul from the base class UInt
+ which is without a sign)
+ */
+ Abs();
+ ss2.Abs();
+
+ c = UInt<value_size>::Mul(ss2);
+ c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
+
+ if( ss1_is_sign != ss2_is_sign )
+ SetSign();
+
+ return c;
+ }
+
+
+ /*!
+ division this = this / ss2
+ returned values:
+ 0 - ok
+ 1 - division by zero
+
+ for example: (result means 'this')
+ 20 / 3 --> result: 6 remainder: 2
+ -20 / 3 --> result: -6 remainder: -2
+ 20 / -3 --> result: -6 remainder: 2
+ -20 / -3 --> result: 6 remainder: -2
+
+ in other words: this(old) = ss2 * this(new)(result) + remainder
+ */
+ uint Div(Int<value_size> ss2, Int<value_size> * remainder = 0)
+ {
+ bool ss1_is_sign, ss2_is_sign;
+
+ ss1_is_sign = IsSign();
+ ss2_is_sign = ss2.IsSign();
+
+ /*
+ we don't have to test the carry from Abs as well as in Mul
+ */
+ Abs();
+ ss2.Abs();
+
+ uint c = UInt<value_size>::Div(ss2, remainder);
+
+ if( ss1_is_sign != ss2_is_sign )
+ SetSign();
+
+ if( ss1_is_sign && remainder )
+ remainder->SetSign();
+
+ return c;
+ }
+
+ uint Div(const Int<value_size> & ss2, Int<value_size> & remainder)
+ {
+ return Div(ss2, &remainder);
+ }
+
+
+ /*!
+ division this = this / ss2 (ss2 is int)
+ returned values:
+ 0 - ok
+ 1 - division by zero
+
+ for example: (result means 'this')
+ 20 / 3 --> result: 6 remainder: 2
+ -20 / 3 --> result: -6 remainder: -2
+ 20 / -3 --> result: -6 remainder: 2
+ -20 / -3 --> result: 6 remainder: -2
+
+ in other words: this(old) = ss2 * this(new)(result) + remainder
+ */
+ uint DivInt(sint ss2, sint * remainder = 0)
+ {
+ bool ss1_is_sign, ss2_is_sign;
+
+ ss1_is_sign = IsSign();
+
+ /*
+ we don't have to test the carry from Abs as well as in Mul
+ */
+ Abs();
+
+ if( ss2 < 0 )
+ {
+ ss2 = -ss2;
+ ss2_is_sign = true;
+ }
+ else
+ {
+ ss2_is_sign = false;
+ }
+
+ uint rem;
+ uint c = UInt<value_size>::DivInt((uint)ss2, &rem);
+
+ if( ss1_is_sign != ss2_is_sign )
+ SetSign();
+
+ if( remainder )
+ {
+ if( ss1_is_sign )
+ *remainder = -sint(rem);
+ else
+ *remainder = sint(rem);
+ }
+
+ return c;
+ }
+
+
+ uint DivInt(sint ss2, sint & remainder)
+ {
+ return DivInt(ss2, &remainder);
+ }
+
+
+private:
+
+
+ /*!
+ power this = this ^ pow
+ this can be negative
+ pow is >= 0
+ */
+ uint Pow2(const Int<value_size> & pow)
+ {
+ bool was_sign = IsSign();
+ uint c = 0;
+
+ if( was_sign )
+ c += Abs();
+
+ uint c_temp = UInt<value_size>::Pow(pow);
+ if( c_temp > 0 )
+ return c_temp; // c_temp can be: 0, 1 or 2
+
+ if( was_sign && (pow.table[0] & 1) == 1 )
+ // negative value to the power of odd number is negative
+ c += ChangeSign();
+
+ return (c==0)? 0 : 1;
+ }
+
+
+public:
+
+
+ /*!
+ power this = this ^ pow
+
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - incorrect arguments 0^0 or 0^(-something)
+ */
+ uint Pow(Int<value_size> pow)
+ {
+ if( !pow.IsSign() )
+ return Pow2(pow);
+
+ if( UInt<value_size>::IsZero() )
+ // if 'pow' is negative then
+ // 'this' must be different from zero
+ return 2;
+
+ if( pow.ChangeSign() )
+ return 1;
+
+ Int<value_size> t(*this);
+ uint c_temp = t.Pow2(pow);
+ if( c_temp > 0 )
+ return c_temp;
+
+ UInt<value_size>::SetOne();
+ if( Div(t) )
+ return 1;
+
+ return 0;
+ }
+
+
+
+ /*!
+ *
+ * convertion methods
+ *
+ */
+private:
+
+
+ /*!
+ an auxiliary method for converting both from UInt and Int
+ */
+ template<uint argument_size>
+ uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
+ {
+ uint min_size = (value_size < argument_size)? value_size : argument_size;
+ uint i;
+
+ for(i=0 ; i<min_size ; ++i)
+ UInt<value_size>::table[i] = p.table[i];
+
+
+ if( value_size > argument_size )
+ {
+ uint fill;
+
+ if( UInt_type )
+ fill = 0;
+ else
+ fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
+ TTMATH_UINT_MAX_VALUE : 0;
+
+ // 'this' is longer than 'p'
+ for( ; i<value_size ; ++i)
+ UInt<value_size>::table[i] = fill;
+ }
+ else
+ {
+ uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
+ TTMATH_UINT_MAX_VALUE : 0;
+
+ if( UInt_type && test!=0 )
+ return 1;
+
+ for( ; i<argument_size ; ++i)
+ if( p.table[i] != test )
+ return 1;
+ }
+
+ return 0;
+ }
+
+public:
+
+ /*!
+ this method converts an Int<another_size> type into this class
+
+ this operation has mainly sense if the value from p
+ can be held in this type
+
+ it returns a carry if the value 'p' is too big
+ */
+ template<uint argument_size>
+ uint FromInt(const Int<argument_size> & p)
+ {
+ return FromUIntOrInt(p, false);
+ }
+
+
+ /*!
+ this method converts the sint type into this class
+ */
+ uint FromInt(sint value)
+ {
+ uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
+
+ for(uint i=1 ; i<value_size ; ++i)
+ UInt<value_size>::table[i] = fill;
+
+ UInt<value_size>::table[0] = uint(value);
+
+ // there'll never be a carry here
+ return 0;
+ }
+
+
+ /*!
+ this method converts UInt<another_size> into this class
+ */
+ template<uint argument_size>
+ uint FromUInt(const UInt<argument_size> & p)
+ {
+ return FromUIntOrInt(p, true);
+ }
+
+
+ /*!
+ this method converts UInt<another_size> into this class
+ */
+ template<uint argument_size>
+ uint FromInt(const UInt<argument_size> & p)
+ {
+ return FromUIntOrInt(p, true);
+ }
+
+
+ /*!
+ this method converts the uint type into this class
+ */
+ uint FromUInt(uint value)
+ {
+ for(uint i=1 ; i<value_size ; ++i)
+ UInt<value_size>::table[i] = 0;
+
+ UInt<value_size>::table[0] = value;
+
+ // there can be a carry here when the size of this value is equal one word
+ // and the 'value' has the highest bit set
+ if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts the uint type into this class
+ */
+ uint FromInt(uint value)
+ {
+ return FromUInt(value);
+ }
+
+
+ /*!
+ the default assignment operator
+ */
+ Int<value_size> & operator=(const Int<value_size> & p)
+ {
+ FromInt(p);
+
+ return *this;
+ }
+
+
+ /*!
+ this operator converts an Int<another_size> type to this class
+
+ it doesn't return a carry
+ */
+ template<uint argument_size>
+ Int<value_size> & operator=(const Int<argument_size> & p)
+ {
+ FromInt(p);
+
+ return *this;
+ }
+
+
+ /*!
+ this method converts the sint type to this class
+ */
+ Int<value_size> & operator=(sint i)
+ {
+ FromInt(i);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting the uint to this class
+ */
+ Int(sint i)
+ {
+ FromInt(i);
+ }
+
+
+ /*!
+ a copy constructor
+ */
+ Int(const Int<value_size> & u)
+ {
+ FromInt(u);
+ }
+
+
+ /*!
+ a constructor for copying from another types
+ */
+ template<uint argument_size>
+ Int(const Int<argument_size> & u)
+ {
+ // look that 'size' we still set as 'value_size' and not as u.value_size
+ FromInt(u);
+ }
+
+
+
+ /*!
+ this operator converts an UInt<another_size> type to this class
+
+ it doesn't return a carry
+ */
+ template<uint argument_size>
+ Int<value_size> & operator=(const UInt<argument_size> & p)
+ {
+ FromUInt(p);
+
+ return *this;
+ }
+
+
+ /*!
+ this method converts the Uint type to this class
+ */
+ Int<value_size> & operator=(uint i)
+ {
+ FromUInt(i);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting the uint to this class
+ */
+ Int(uint i)
+ {
+ FromUInt(i);
+ }
+
+
+ /*!
+ a constructor for copying from another types
+ */
+ template<uint argument_size>
+ Int(const UInt<argument_size> & u)
+ {
+ // look that 'size' we still set as 'value_size' and not as u.value_size
+ FromUInt(u);
+ }
+
+
+
+#ifdef TTMATH_PLATFORM32
+
+
+ /*!
+ this method converts unsigned 64 bit int type to this class
+ ***this method is created only on a 32bit platform***
+ */
+ uint FromUInt(ulint n)
+ {
+ uint c = UInt<value_size>::FromUInt(n);
+
+ if( c )
+ return 1;
+
+ if( value_size == 1 )
+ return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
+
+ if( value_size == 2 )
+ return ((UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts unsigned 64 bit int type to this class
+ ***this method is created only on a 32bit platform***
+ */
+ uint FromInt(ulint n)
+ {
+ return FromUInt(n);
+ }
+
+
+ /*!
+ this method converts signed 64 bit int type to this class
+ ***this method is created only on a 32bit platform***
+ */
+ uint FromInt(slint n)
+ {
+ uint mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0;
+
+ UInt<value_size>::table[0] = (uint)(ulint)n;
+
+ if( value_size == 1 )
+ {
+ if( uint(ulint(n) >> 32) != mask )
+ return 1;
+
+ return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
+ }
+
+ UInt<value_size>::table[1] = (uint)(ulint(n) >> 32);
+
+ for(uint i=2 ; i<value_size ; ++i)
+ UInt<value_size>::table[i] = mask;
+
+ return 0;
+ }
+
+
+ /*!
+ this operator converts unsigned 64 bit int type to this class
+ ***this operator is created only on a 32bit platform***
+ */
+ Int<value_size> & operator=(ulint n)
+ {
+ FromUInt(n);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting unsigned 64 bit int to this class
+ ***this constructor is created only on a 32bit platform***
+ */
+ Int(ulint n)
+ {
+ FromUInt(n);
+ }
+
+
+ /*!
+ this operator converts signed 64 bit int type to this class
+ ***this operator is created only on a 32bit platform***
+ */
+ Int<value_size> & operator=(slint n)
+ {
+ FromInt(n);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting signed 64 bit int to this class
+ ***this constructor is created only on a 32bit platform***
+ */
+ Int(slint n)
+ {
+ FromInt(n);
+ }
+
+#endif
+
+
+
+
+#ifdef TTMATH_PLATFORM64
+
+ /*!
+ this method converts 32 bit unsigned int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ uint FromUInt(unsigned int i)
+ {
+ return FromUInt(uint(i));
+ }
+
+
+ /*!
+ this method converts 32 bit unsigned int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ uint FromInt(unsigned int i)
+ {
+ return FromUInt(i);
+ }
+
+
+ /*!
+ this method converts 32 bit signed int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ uint FromInt(signed int i)
+ {
+ return FromInt(sint(i));
+ }
+
+
+ /*!
+ this method converts 32 bit unsigned int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ Int<value_size> & operator=(unsigned int i)
+ {
+ FromUInt(i);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting 32 bit unsigned int to this class
+ ***this constructor is created only on a 64bit platform***
+ */
+ Int(unsigned int i)
+ {
+ FromUInt(i);
+ }
+
+
+ /*!
+ this operator converts 32 bit signed int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ Int<value_size> & operator=(signed int i)
+ {
+ FromInt(i);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting 32 bit signed int to this class
+ ***this constructor is created only on a 64bit platform***
+ */
+ Int(signed int i)
+ {
+ FromInt(i);
+ }
+
+#endif
+
+
+
+ /*!
+ a constructor for converting string to this class (with the base=10)
+ */
+ Int(const char * s)
+ {
+ FromString(s);
+ }
+
+
+ /*!
+ a constructor for converting a string to this class (with the base=10)
+ */
+ Int(const std::string & s)
+ {
+ FromString( s.c_str() );
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ a constructor for converting string to this class (with the base=10)
+ */
+ Int(const wchar_t * s)
+ {
+ FromString(s);
+ }
+
+
+ /*!
+ a constructor for converting a string to this class (with the base=10)
+ */
+ Int(const std::wstring & s)
+ {
+ FromString( s.c_str() );
+ }
+
+#endif
+
+
+ /*!
+ a default constructor
+
+ we don't clear table etc.
+ */
+ Int()
+ {
+ }
+
+
+ /*!
+ the destructor
+ */
+ ~Int()
+ {
+ }
+
+
+ /*!
+ this method returns the lowest value from table with a sign
+
+ we must be sure when we using this method whether the value
+ will hold in an sint type or not (the rest value from table must be zero or -1)
+ */
+ sint ToInt() const
+ {
+ return sint( UInt<value_size>::table[0] );
+ }
+
+
+ /*!
+ this method converts the value to uint type
+ can return a carry if the value is too long to store it in uint type
+ */
+ uint ToUInt(uint & result) const
+ {
+ uint c = UInt<value_size>::ToUInt(result);
+
+ if( value_size == 1 )
+ return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
+
+ return c;
+ }
+
+
+ /*!
+ this method converts the value to uint type
+ can return a carry if the value is too long to store it in uint type
+ */
+ uint ToInt(uint & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts the value to sint type
+ can return a carry if the value is too long to store it in sint type
+ */
+ uint ToInt(sint & result) const
+ {
+ result = sint( UInt<value_size>::table[0] );
+ uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
+
+ if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
+ return 1;
+
+ for(uint i=1 ; i<value_size ; ++i)
+ if( UInt<value_size>::table[i] != mask )
+ return 1;
+
+ return 0;
+ }
+
+
+#ifdef TTMATH_PLATFORM32
+
+ /*!
+ this method converts the value to ulint type (64 bit unsigned integer)
+ can return a carry if the value is too long to store it in ulint type
+ *** this method is created only on a 32 bit platform ***
+ */
+ uint ToUInt(ulint & result) const
+ {
+ uint c = UInt<value_size>::ToUInt(result);
+
+ if( value_size == 1 )
+ return (UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
+
+ if( value_size == 2 )
+ return (UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
+
+ return c;
+ }
+
+
+ /*!
+ this method converts the value to ulint type (64 bit unsigned integer)
+ can return a carry if the value is too long to store it in ulint type
+ *** this method is created only on a 32 bit platform ***
+ */
+ uint ToInt(ulint & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts the value to slint type (64 bit signed integer)
+ can return a carry if the value is too long to store it in slint type
+ *** this method is created only on a 32 bit platform ***
+ */
+ uint ToInt(slint & result) const
+ {
+ if( value_size == 1 )
+ {
+ result = slint(sint(UInt<value_size>::table[0]));
+ }
+ else
+ {
+ uint low = UInt<value_size>::table[0];
+ uint high = UInt<value_size>::table[1];
+
+ result = low;
+ result |= (ulint(high) << TTMATH_BITS_PER_UINT);
+
+ uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
+
+ if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
+ return 1;
+
+ for(uint i=2 ; i<value_size ; ++i)
+ if( UInt<value_size>::table[i] != mask )
+ return 1;
+ }
+
+ return 0;
+ }
+
+#endif
+
+
+
+#ifdef TTMATH_PLATFORM64
+
+ /*!
+ this method converts the value to a 32 bit unsigned integer
+ can return a carry if the value is too long to store it in this type
+ *** this method is created only on a 64 bit platform ***
+ */
+ uint ToUInt(unsigned int & result) const
+ {
+ uint c = UInt<value_size>::ToUInt(result);
+
+ if( c || IsSign() )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts the value to a 32 bit unsigned integer
+ can return a carry if the value is too long to store it in this type
+ *** this method is created only on a 64 bit platform ***
+ */
+ uint ToInt(unsigned int & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts the value to a 32 bit signed integer
+ can return a carry if the value is too long to store it in this type
+ *** this method is created only on a 64 bit platform ***
+ */
+ uint ToInt(int & result) const
+ {
+ uint first = UInt<value_size>::table[0];
+
+ result = int(first);
+ uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
+
+ if( (first >> 31) != (mask >> 31) )
+ return 1;
+
+ for(uint i=1 ; i<value_size ; ++i)
+ if( UInt<value_size>::table[i] != mask )
+ return 1;
+
+ return 0;
+ }
+
+#endif
+
+
+
+
+private:
+
+ /*!
+ an auxiliary method for converting to a string
+ */
+ template<class string_type>
+ void ToStringBase(string_type & result, uint b = 10) const
+ {
+ if( IsSign() )
+ {
+ Int<value_size> temp(*this);
+ temp.Abs();
+ temp.UInt<value_size>::ToStringBase(result, b, true);
+ }
+ else
+ {
+ UInt<value_size>::ToStringBase(result, b, false);
+ }
+ }
+
+public:
+
+ /*!
+ this method converts the value to a string with a base equal 'b'
+ */
+ void ToString(std::string & result, uint b = 10) const
+ {
+ return ToStringBase(result, b);
+ }
+
+
+ /*!
+ this method converts the value to a string with a base equal 'b'
+ */
+ std::string ToString(uint b = 10) const
+ {
+ std::string result;
+ ToStringBase(result, b);
+
+ return result;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ this method converts the value to a string with a base equal 'b'
+ */
+ void ToString(std::wstring & result, uint b = 10) const
+ {
+ return ToStringBase(result, b);
+ }
+
+
+ /*!
+ this method converts the value to a string with a base equal 'b'
+ */
+ std::wstring ToWString(uint b = 10) const
+ {
+ std::wstring result;
+ ToStringBase(result, b);
+
+ return result;
+ }
+
+#endif
+
+
+
+private:
+
+ /*!
+ an auxiliary method for converting from a string
+ */
+ template<class char_type>
+ uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
+ {
+ bool is_sign = false;
+
+ Misc::SkipWhiteCharacters(s);
+
+ if( *s == '-' )
+ {
+ is_sign = true;
+ Misc::SkipWhiteCharacters(++s);
+ }
+ else
+ if( *s == '+' )
+ {
+ Misc::SkipWhiteCharacters(++s);
+ }
+
+ if( UInt<value_size>::FromString(s,b,after_source,value_read) )
+ return 1;
+
+ if( is_sign )
+ {
+ Int<value_size> mmin;
+
+ mmin.SetMin();
+
+ /*
+ the reference to mmin will be automatically converted to the reference
+ to UInt type
+ (this value can be equal mmin -- look at a description in ChangeSign())
+ */
+ if( UInt<value_size>::operator>( mmin ) )
+ return 1;
+
+ /*
+ if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
+ */
+ ChangeSign();
+ }
+ else
+ {
+ Int<value_size> mmax;
+
+ mmax.SetMax();
+
+ if( UInt<value_size>::operator>( mmax ) )
+ return 1;
+ }
+
+ return 0;
+ }
+
+
+public:
+
+ /*!
+ this method converts a string into its value
+ it returns carry=1 if the value will be too big or an incorrect base 'b' is given
+
+ string is ended with a non-digit value, for example:
+ "-12" will be translated to -12
+ as well as:
+ "- 12foo" will be translated to -12 too
+
+ existing first white characters will be ommited
+ (between '-' and a first digit can be white characters too)
+
+ after_source (if exists) is pointing at the end of the parsed string
+
+ value_read (if exists) tells whether something has actually been read (at least one digit)
+ */
+ uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
+ {
+ return FromStringBase(s, b, after_source, value_read);
+ }
+
+
+ /*!
+ this method converts a string into its value
+ */
+ uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+ {
+ return FromStringBase(s, b, after_source, value_read);
+ }
+
+
+ /*!
+ this method converts a string into its value
+ it returns carry=1 if the value will be too big or an incorrect base 'b' is given
+ */
+ uint FromString(const std::string & s, uint b = 10)
+ {
+ return FromString( s.c_str(), b );
+ }
+
+
+ /*!
+ this operator converts a string into its value (with base = 10)
+ */
+ Int<value_size> & operator=(const char * s)
+ {
+ FromString(s);
+
+ return *this;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+
+ /*!
+ this method converts a string into its value
+ it returns carry=1 if the value will be too big or an incorrect base 'b' is given
+ */
+ uint FromString(const std::wstring & s, uint b = 10)
+ {
+ return FromString( s.c_str(), b );
+ }
+
+
+ /*!
+ this operator converts a string into its value (with base = 10)
+ */
+ Int<value_size> & operator=(const wchar_t * s)
+ {
+ FromString(s);
+
+ return *this;
+ }
+
+
+ /*!
+ this operator converts a string into its value (with base = 10)
+ */
+ Int<value_size> & operator=(const std::wstring & s)
+ {
+ FromString( s.c_str() );
+
+ return *this;
+ }
+
+#endif
+
+
+ /*!
+ this operator converts a string into its value (with base = 10)
+ */
+ Int<value_size> & operator=(const std::string & s)
+ {
+ FromString( s.c_str() );
+
+ return *this;
+ }
+
+
+
+ /*!
+ *
+ * methods for comparing
+ *
+ *
+ */
+
+ bool operator==(const Int<value_size> & l) const
+ {
+ return UInt<value_size>::operator==(l);
+ }
+
+ bool operator!=(const Int<value_size> & l) const
+ {
+ return UInt<value_size>::operator!=(l);
+ }
+
+ bool operator<(const Int<value_size> & l) const
+ {
+ sint i=value_size-1;
+
+ sint a1 = sint(UInt<value_size>::table[i]);
+ sint a2 = sint(l.table[i]);
+
+ if( a1 != a2 )
+ return a1 < a2;
+
+
+ for(--i ; i>=0 ; --i)
+ {
+ if( UInt<value_size>::table[i] != l.table[i] )
+ // comparison as unsigned int
+ return UInt<value_size>::table[i] < l.table[i];
+ }
+
+ // they're equal
+ return false;
+ }
+
+
+ bool operator>(const Int<value_size> & l) const
+ {
+ sint i=value_size-1;
+
+ sint a1 = sint(UInt<value_size>::table[i]);
+ sint a2 = sint(l.table[i]);
+
+ if( a1 != a2 )
+ return a1 > a2;
+
+
+ for(--i ; i>=0 ; --i)
+ {
+ if( UInt<value_size>::table[i] != l.table[i] )
+ // comparison as unsigned int
+ return UInt<value_size>::table[i] > l.table[i];
+ }
+
+ // they're equal
+ return false;
+ }
+
+
+ bool operator<=(const Int<value_size> & l) const
+ {
+ sint i=value_size-1;
+
+ sint a1 = sint(UInt<value_size>::table[i]);
+ sint a2 = sint(l.table[i]);
+
+ if( a1 != a2 )
+ return a1 < a2;
+
+
+ for(--i ; i>=0 ; --i)
+ {
+ if( UInt<value_size>::table[i] != l.table[i] )
+ // comparison as unsigned int
+ return UInt<value_size>::table[i] < l.table[i];
+ }
+
+ // they're equal
+ return true;
+ }
+
+
+ bool operator>=(const Int<value_size> & l) const
+ {
+ sint i=value_size-1;
+
+ sint a1 = sint(UInt<value_size>::table[i]);
+ sint a2 = sint(l.table[i]);
+
+ if( a1 != a2 )
+ return a1 > a2;
+
+
+ for(--i ; i>=0 ; --i)
+ {
+ if( UInt<value_size>::table[i] != l.table[i] )
+ // comparison as unsigned int
+ return UInt<value_size>::table[i] > l.table[i];
+ }
+
+ // they're equal
+ return true;
+ }
+
+
+
+ /*!
+ *
+ * standard mathematical operators
+ *
+ */
+
+
+ /*!
+ an operator for changing the sign
+
+ it's not changing 'this' but the changed value will be returned
+ */
+ Int<value_size> operator-() const
+ {
+ Int<value_size> temp(*this);
+
+ temp.ChangeSign();
+
+ return temp;
+ }
+
+
+ Int<value_size> operator-(const Int<value_size> & p2) const
+ {
+ Int<value_size> temp(*this);
+
+ temp.Sub(p2);
+
+ return temp;
+ }
+
+
+ Int<value_size> & operator-=(const Int<value_size> & p2)
+ {
+ Sub(p2);
+
+ return *this;
+ }
+
+
+ Int<value_size> operator+(const Int<value_size> & p2) const
+ {
+ Int<value_size> temp(*this);
+
+ temp.Add(p2);
+
+ return temp;
+ }
+
+
+ Int<value_size> & operator+=(const Int<value_size> & p2)
+ {
+ Add(p2);
+
+ return *this;
+ }
+
+
+ Int<value_size> operator*(const Int<value_size> & p2) const
+ {
+ Int<value_size> temp(*this);
+
+ temp.Mul(p2);
+
+ return temp;
+ }
+
+
+ Int<value_size> & operator*=(const Int<value_size> & p2)
+ {
+ Mul(p2);
+
+ return *this;
+ }
+
+
+ Int<value_size> operator/(const Int<value_size> & p2) const
+ {
+ Int<value_size> temp(*this);
+
+ temp.Div(p2);
+
+ return temp;
+ }
+
+
+ Int<value_size> & operator/=(const Int<value_size> & p2)
+ {
+ Div(p2);
+
+ return *this;
+ }
+
+
+ Int<value_size> operator%(const Int<value_size> & p2) const
+ {
+ Int<value_size> temp(*this);
+ Int<value_size> remainder;
+
+ temp.Div(p2, remainder);
+
+ return remainder;
+ }
+
+
+ Int<value_size> & operator%=(const Int<value_size> & p2)
+ {
+ Int<value_size> remainder;
+
+ Div(p2, remainder);
+ operator=(remainder);
+
+ return *this;
+ }
+
+
+ /*!
+ Prefix operator e.g. ++variable
+ */
+ UInt<value_size> & operator++()
+ {
+ AddOne();
+
+ return *this;
+ }
+
+
+ /*!
+ Postfix operator e.g. variable++
+ */
+ UInt<value_size> operator++(int)
+ {
+ UInt<value_size> temp( *this );
+
+ AddOne();
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator--()
+ {
+ SubOne();
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator--(int)
+ {
+ UInt<value_size> temp( *this );
+
+ SubOne();
+
+ return temp;
+ }
+
+
+
+ /*!
+ *
+ * input/output operators for standard streams
+ *
+ */
+
+private:
+
+ /*!
+ an auxiliary method for outputing to standard streams
+ */
+ template<class ostream_type, class string_type>
+ static ostream_type & OutputToStream(ostream_type & s, const Int<value_size> & l)
+ {
+ string_type ss;
+
+ l.ToString(ss);
+ s << ss;
+
+ return s;
+ }
+
+
+
+public:
+
+
+ /*!
+ output to standard streams
+ */
+ friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
+ {
+ return OutputToStream<std::ostream, std::string>(s, l);
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ output to standard streams
+ */
+ friend std::wostream & operator<<(std::wostream & s, const Int<value_size> & l)
+ {
+ return OutputToStream<std::wostream, std::wstring>(s, l);
+ }
+
+#endif
+
+
+
+private:
+
+ /*!
+ an auxiliary method for converting from a string
+ */
+ template<class istream_type, class string_type, class char_type>
+ static istream_type & InputFromStream(istream_type & s, Int<value_size> & l)
+ {
+ string_type ss;
+
+ // char or wchar_t for operator>>
+ char_type z;
+
+ // operator>> omits white characters if they're set for ommiting
+ s >> z;
+
+ if( z=='-' || z=='+' )
+ {
+ ss += z;
+ s >> z; // we're reading a next character (white characters can be ommited)
+ }
+
+ // we're reading only digits (base=10)
+ while( s.good() && Misc::CharToDigit(z, 10)>=0 )
+ {
+ ss += z;
+ z = static_cast<char_type>(s.get());
+ }
+
+ // we're leaving the last readed character
+ // (it's not belonging to the value)
+ s.unget();
+
+ l.FromString(ss);
+
+ return s;
+ }
+
+
+public:
+
+ /*!
+ input from standard streams
+ */
+ friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
+ {
+ return InputFromStream<std::istream, std::string, char>(s, l);
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ input from standard streams
+ */
+ friend std::wistream & operator>>(std::wistream & s, Int<value_size> & l)
+ {
+ return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
+ }
+#endif
+
+
+};
+
+} // namespace
+
+#endif
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h
new file mode 100644
index 0000000..330a43a
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h
@@ -0,0 +1,250 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef headerfilettmathmisc
+#define headerfilettmathmisc
+
+
+/*!
+ \file ttmathmisc.h
+ \brief some helpful functions
+*/
+
+
+#include <string>
+
+
+namespace ttmath
+{
+
+/*!
+ some helpful functions
+*/
+class Misc
+{
+public:
+
+
+/*
+ *
+ * AssignString(result, str)
+ * result = str
+ *
+ */
+
+/*!
+ result = str
+*/
+static void AssignString(std::string & result, const char * str)
+{
+ result = str;
+}
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+/*!
+ result = str
+*/
+static void AssignString(std::wstring & result, const char * str)
+{
+ result.clear();
+
+ for( ; *str ; ++str )
+ result += *str;
+}
+
+
+/*!
+ result = str
+*/
+static void AssignString(std::wstring & result, const std::string & str)
+{
+ return AssignString(result, str.c_str());
+}
+
+
+/*!
+ result = str
+*/
+static void AssignString(std::string & result, const wchar_t * str)
+{
+ result.clear();
+
+ for( ; *str ; ++str )
+ result += static_cast<char>(*str);
+}
+
+
+/*!
+ result = str
+*/
+static void AssignString(std::string & result, const std::wstring & str)
+{
+ return AssignString(result, str.c_str());
+}
+
+#endif
+
+
+/*
+ *
+ * AddString(result, str)
+ * result += str
+ *
+ */
+
+
+/*!
+ result += str
+*/
+static void AddString(std::string & result, const char * str)
+{
+ result += str;
+}
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+/*!
+ result += str
+*/
+static void AddString(std::wstring & result, const char * str)
+{
+ for( ; *str ; ++str )
+ result += *str;
+}
+
+#endif
+
+
+/*
+ this method omits any white characters from the string
+ char_type is char or wchar_t
+*/
+template<class char_type>
+static void SkipWhiteCharacters(const char_type * & c)
+{
+ // 13 is at the end in a DOS text file (\r\n)
+ while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
+ ++c;
+}
+
+
+
+
+/*!
+ this static method converts one character into its value
+
+ for example:
+ 1 -> 1
+ 8 -> 8
+ A -> 10
+ f -> 15
+
+ this method don't check whether c is correct or not
+*/
+static uint CharToDigit(uint c)
+{
+ if(c>='0' && c<='9')
+ return c-'0';
+
+ if(c>='a' && c<='z')
+ return c-'a'+10;
+
+return c-'A'+10;
+}
+
+
+/*!
+ this method changes a character 'c' into its value
+ (if there can't be a correct value it returns -1)
+
+ for example:
+ c=2, base=10 -> function returns 2
+ c=A, base=10 -> function returns -1
+ c=A, base=16 -> function returns 10
+*/
+static sint CharToDigit(uint c, uint base)
+{
+ if( c>='0' && c<='9' )
+ c=c-'0';
+ else
+ if( c>='a' && c<='z' )
+ c=c-'a'+10;
+ else
+ if( c>='A' && c<='Z' )
+ c=c-'A'+10;
+ else
+ return -1;
+
+
+ if( c >= base )
+ return -1;
+
+
+return sint(c);
+}
+
+
+
+/*!
+ this method converts a digit into a char
+ digit should be from <0,F>
+ (we don't have to get a base)
+
+ for example:
+ 1 -> 1
+ 8 -> 8
+ 10 -> A
+ 15 -> F
+*/
+static uint DigitToChar(uint digit)
+{
+ if( digit < 10 )
+ return digit + '0';
+
+return digit - 10 + 'A';
+}
+
+
+}; // struct Misc
+
+}
+
+
+#endif
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h
new file mode 100644
index 0000000..c35026b
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h
@@ -0,0 +1,809 @@
+/*
+ * This file is a part of TTMath Mathematical Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef headerfilettmathobject
+#define headerfilettmathobject
+
+/*!
+ \file ttmathobjects.h
+ \brief Mathematic functions.
+*/
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+
+#include "ttmathtypes.h"
+#include "ttmathmisc.h"
+
+
+namespace ttmath
+{
+
+/*!
+ objects of this class are used with the mathematical parser
+ they hold variables or functions defined by a user
+
+ each object has its own table in which we're keeping variables or functions
+*/
+class Objects
+{
+public:
+
+
+ /*!
+ one item (variable or function)
+ 'items' will be on the table
+ */
+ struct Item
+ {
+ // name of a variable of a function
+ // internally we store variables and funcions as std::string (not std::wstring even when wide characters are used)
+ std::string value;
+
+ // number of parameters required by the function
+ // (if there's a variable this 'param' is ignored)
+ int param;
+
+ Item() {}
+ Item(const std::string & v, int p) : value(v), param(p) {}
+ };
+
+ // 'Table' is the type of our table
+ typedef std::map<std::string, Item> Table;
+ typedef Table::iterator Iterator;
+ typedef Table::const_iterator CIterator;
+
+
+
+ /*!
+ this method returns true if a character 'c' is a character
+ which can be in a name
+
+ if 'can_be_digit' is true that means when the 'c' is a digit this
+ method returns true otherwise it returns false
+ */
+ static bool CorrectCharacter(int c, bool can_be_digit)
+ {
+ if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
+ return true;
+
+ if( can_be_digit && ((c>='0' && c<='9') || c=='_') )
+ return true;
+
+ return false;
+ }
+
+
+ /*!
+ this method returns true if the name can be as a name of an object
+ */
+ template<class string_type>
+ static bool IsNameCorrect(const string_type & name)
+ {
+ if( name.empty() )
+ return false;
+
+ if( !CorrectCharacter(name[0], false) )
+ return false;
+
+ typename string_type::const_iterator i = name.begin();
+
+ for(++i ; i!=name.end() ; ++i)
+ if( !CorrectCharacter(*i, true) )
+ return false;
+
+ return true;
+ }
+
+
+ /*!
+ this method returns true if such an object is defined (name exists)
+ */
+ bool IsDefined(const std::string & name)
+ {
+ Iterator i = table.find(name);
+
+ if( i != table.end() )
+ // we have this object in our table
+ return true;
+
+ return false;
+ }
+
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ this method returns true if such an object is defined (name exists)
+ */
+ bool IsDefined(const std::wstring & name)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(name) )
+ return false;
+
+ Misc::AssignString(str_tmp1, name);
+
+ return IsDefined(str_tmp1);
+ }
+
+#endif
+
+
+ /*!
+ this method adds one object (variable of function) into the table
+ */
+ ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
+ {
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Iterator i = table.find(name);
+
+ if( i != table.end() )
+ // we have this object in our table
+ return err_object_exists;
+
+ table.insert( std::make_pair(name, Item(value, param)) );
+
+ return err_ok;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ this method adds one object (variable of function) into the table
+ */
+ ErrorCode Add(const std::wstring & name, const std::wstring & value, int param = 0)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Misc::AssignString(str_tmp1, name);
+ Misc::AssignString(str_tmp2, value);
+
+ return Add(str_tmp1, str_tmp2, param);
+ }
+
+#endif
+
+
+ /*!
+ this method returns 'true' if the table is empty
+ */
+ bool Empty() const
+ {
+ return table.empty();
+ }
+
+
+ /*!
+ this method clears the table
+ */
+ void Clear()
+ {
+ return table.clear();
+ }
+
+
+ /*!
+ this method returns 'const_iterator' on the first item on the table
+ */
+ CIterator Begin() const
+ {
+ return table.begin();
+ }
+
+
+ /*!
+ this method returns 'const_iterator' pointing at the space after last item
+ (returns table.end())
+ */
+ CIterator End() const
+ {
+ return table.end();
+ }
+
+
+ /*!
+ this method changes the value and the number of parameters for a specific object
+ */
+ ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0)
+ {
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Iterator i = table.find(name);
+
+ if( i == table.end() )
+ return err_unknown_object;
+
+ i->second.value = value;
+ i->second.param = param;
+
+ return err_ok;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+
+ /*!
+ this method changes the value and the number of parameters for a specific object
+ */
+ ErrorCode EditValue(const std::wstring & name, const std::wstring & value, int param = 0)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Misc::AssignString(str_tmp1, name);
+ Misc::AssignString(str_tmp2, value);
+
+ return EditValue(str_tmp1, str_tmp2, param);
+ }
+
+#endif
+
+
+ /*!
+ this method changes the name of a specific object
+ */
+ ErrorCode EditName(const std::string & old_name, const std::string & new_name)
+ {
+ if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
+ return err_incorrect_name;
+
+ Iterator old_i = table.find(old_name);
+ if( old_i == table.end() )
+ return err_unknown_object;
+
+ if( old_name == new_name )
+ // the new name is the same as the old one
+ // we treat it as a normal situation
+ return err_ok;
+
+ ErrorCode err = Add(new_name, old_i->second.value, old_i->second.param);
+
+ if( err == err_ok )
+ {
+ old_i = table.find(old_name);
+ TTMATH_ASSERT( old_i != table.end() )
+
+ table.erase(old_i);
+ }
+
+ return err;
+ }
+
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+
+ /*!
+ this method changes the name of a specific object
+ */
+ ErrorCode EditName(const std::wstring & old_name, const std::wstring & new_name)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
+ return err_incorrect_name;
+
+ Misc::AssignString(str_tmp1, old_name);
+ Misc::AssignString(str_tmp2, new_name);
+
+ return EditName(str_tmp1, str_tmp2);
+ }
+
+#endif
+
+
+ /*!
+ this method deletes an object
+ */
+ ErrorCode Delete(const std::string & name)
+ {
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Iterator i = table.find(name);
+
+ if( i == table.end() )
+ return err_unknown_object;
+
+ table.erase( i );
+
+ return err_ok;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+
+ /*!
+ this method deletes an object
+ */
+ ErrorCode Delete(const std::wstring & name)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Misc::AssignString(str_tmp1, name);
+
+ return Delete(str_tmp1);
+ }
+
+#endif
+
+
+ /*!
+ this method gets the value of a specific object
+ */
+ ErrorCode GetValue(const std::string & name, std::string & value) const
+ {
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ CIterator i = table.find(name);
+
+ if( i == table.end() )
+ {
+ value.clear();
+ return err_unknown_object;
+ }
+
+ value = i->second.value;
+
+ return err_ok;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ this method gets the value of a specific object
+ */
+ ErrorCode GetValue(const std::wstring & name, std::wstring & value)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Misc::AssignString(str_tmp1, name);
+ ErrorCode err = GetValue(str_tmp1, str_tmp2);
+ Misc::AssignString(value, str_tmp2);
+
+ return err;
+ }
+
+#endif
+
+
+ /*!
+ this method gets the value of a specific object
+ (this version is used for not copying the whole string)
+ */
+ ErrorCode GetValue(const std::string & name, const char ** value) const
+ {
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ CIterator i = table.find(name);
+
+ if( i == table.end() )
+ {
+ *value = 0;
+ return err_unknown_object;
+ }
+
+ *value = i->second.value.c_str();
+
+ return err_ok;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ this method gets the value of a specific object
+ (this version is used for not copying the whole string)
+ */
+ ErrorCode GetValue(const std::wstring & name, const char ** value)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Misc::AssignString(str_tmp1, name);
+
+ return GetValue(str_tmp1, value);
+ }
+
+#endif
+
+
+ /*!
+ this method gets the value and the number of parameters
+ of a specific object
+ */
+ ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
+ {
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ CIterator i = table.find(name);
+
+ if( i == table.end() )
+ {
+ value.empty();
+ *param = 0;
+ return err_unknown_object;
+ }
+
+ value = i->second.value;
+ *param = i->second.param;
+
+ return err_ok;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ this method gets the value and the number of parameters
+ of a specific object
+ */
+ ErrorCode GetValueAndParam(const std::wstring & name, std::wstring & value, int * param)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Misc::AssignString(str_tmp1, name);
+ ErrorCode err = GetValueAndParam(str_tmp1, str_tmp2, param);
+ Misc::AssignString(value, str_tmp2);
+
+ return err;
+ }
+
+#endif
+
+
+ /*!
+ this method sets the value and the number of parameters
+ of a specific object
+ (this version is used for not copying the whole string)
+ */
+ ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const
+ {
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ CIterator i = table.find(name);
+
+ if( i == table.end() )
+ {
+ *value = 0;
+ *param = 0;
+ return err_unknown_object;
+ }
+
+ *value = i->second.value.c_str();
+ *param = i->second.param;
+
+ return err_ok;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+
+ /*!
+ this method sets the value and the number of parameters
+ of a specific object
+ (this version is used for not copying the whole string
+ but in fact we make one copying during AssignString())
+ */
+ ErrorCode GetValueAndParam(const std::wstring & name, const char ** value, int * param)
+ {
+ // we should check whether the name (in wide characters) are correct
+ // before calling AssignString() function
+ if( !IsNameCorrect(name) )
+ return err_incorrect_name;
+
+ Misc::AssignString(str_tmp1, name);
+
+ return GetValueAndParam(str_tmp1, value, param);
+ }
+
+
+#endif
+
+
+ /*!
+ this method returns a pointer into the table
+ */
+ Table * GetTable()
+ {
+ return &table;
+ }
+
+
+private:
+
+ Table table;
+ std::string str_tmp1, str_tmp2;
+
+}; // end of class Objects
+
+
+
+
+
+
+
+/*!
+ objects of the class History are used to keep values in functions
+ which take a lot of time during calculating, for instance in the
+ function Factorial(x)
+
+ it means that when we're calculating e.g. Factorial(1000) and the
+ Factorial finds that we have calculated it before, the value (result)
+ is taken from the history
+*/
+template<class ValueType>
+class History
+{
+ /*!
+ one item in the History's object holds a key, a value for the key
+ and a corresponding error code
+ */
+ struct Item
+ {
+ ValueType key, value;
+ ErrorCode err;
+ };
+
+
+ /*!
+ we use std::list for simply deleting the first item
+ but because we're searching through the whole container
+ (in the method Get) the container should not be too big
+ (linear time of searching)
+ */
+ typedef std::list<Item> buffer_type;
+ buffer_type buffer;
+ typename buffer_type::size_type buffer_max_size;
+
+public:
+
+ /*!
+ default constructor
+ default max size of the History's container is 15 items
+ */
+ History()
+ {
+ buffer_max_size = 15;
+ }
+
+
+ /*!
+ a constructor which takes another value of the max size
+ of the History's container
+ */
+ History(typename buffer_type::size_type new_size)
+ {
+ buffer_max_size = new_size;
+ }
+
+
+ /*!
+ this method adds one item into the History
+ if the size of the container is greater than buffer_max_size
+ the first item will be removed
+ */
+ void Add(const ValueType & key, const ValueType & value, ErrorCode err)
+ {
+ Item item;
+ item.key = key;
+ item.value = value;
+ item.err = err;
+
+ buffer.insert( buffer.end(), item );
+
+ if( buffer.size() > buffer_max_size )
+ buffer.erase(buffer.begin());
+ }
+
+
+ /*!
+ this method checks whether we have an item which has the key equal 'key'
+
+ if there's such item the method sets the 'value' and the 'err'
+ and returns true otherwise it returns false and 'value' and 'err'
+ remain unchanged
+ */
+ bool Get(const ValueType & key, ValueType & value, ErrorCode & err)
+ {
+ typename buffer_type::iterator i = buffer.begin();
+
+ for( ; i != buffer.end() ; ++i )
+ {
+ if( i->key == key )
+ {
+ value = i->value;
+ err = i->err;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ /*!
+ this methods deletes an item
+
+ we assume that there is only one item with the 'key'
+ (this methods removes the first one)
+ */
+ bool Remove(const ValueType & key)
+ {
+ typename buffer_type::iterator i = buffer.begin();
+
+ for( ; i != buffer.end() ; ++i )
+ {
+ if( i->key == key )
+ {
+ buffer.erase(i);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+}; // end of class History
+
+
+
+/*!
+ this is an auxiliary class used when calculating Gamma() or Factorial()
+
+ in multithreaded environment you can provide an object of this class to
+ the Gamma() or Factorial() function, e.g;
+ typedef Big<1, 3> MyBig;
+ MyBig x = 123456;
+ CGamma<MyBig> cgamma;
+ std::cout << Gamma(x, cgamma);
+ each thread should have its own CGamma<> object
+
+ in a single-thread environment a CGamma<> object is a static variable
+ in a second version of Gamma() and you don't have to explicitly use it, e.g.
+ typedef Big<1, 3> MyBig;
+ MyBig x = 123456;
+ std::cout << Gamma(x);
+*/
+template<class ValueType>
+struct CGamma
+{
+ /*!
+ this table holds factorials
+ 1
+ 1
+ 2
+ 6
+ 24
+ 120
+ 720
+ .......
+ */
+ std::vector<ValueType> fact;
+
+
+ /*!
+ this table holds Bernoulli numbers
+ 1
+ -0.5
+ 0.166666666666666666666666667
+ 0
+ -0.0333333333333333333333333333
+ 0
+ 0.0238095238095238095238095238
+ 0
+ -0.0333333333333333333333333333
+ 0
+ 0.075757575757575757575757576
+ .....
+ */
+ std::vector<ValueType> bern;
+
+
+ /*!
+ here we store some calculated values
+ (this is for speeding up, if the next argument of Gamma() or Factorial()
+ is in the 'history' then the result we are not calculating but simply
+ return from the 'history' object)
+ */
+ History<ValueType> history;
+
+
+ /*!
+ this method prepares some coefficients: factorials and Bernoulli numbers
+ stored in 'fact' and 'bern' objects
+
+ how many values should be depends on the size of the mantissa - if
+ the mantissa is larger then we must calculate more values
+ for a mantissa which consists of 256 bits (8 words on a 32bit platform)
+ we have to calculate about 30 values (the size of fact and bern will be 30),
+ and for a 2048 bits mantissa we have to calculate 306 coefficients
+
+ you don't have to call this method, these coefficients will be automatically calculated
+ when they are needed
+
+ you must note that calculating these coefficients is a little time-consuming operation,
+ (especially when the mantissa is large) and first call to Gamma() or Factorial()
+ can take more time than next calls, and in the end this is the point when InitAll()
+ comes in handy: you can call this method somewhere at the beginning of your program
+ */
+ void InitAll();
+ // definition is in ttmath.h
+};
+
+
+
+
+} // namespace
+
+#endif
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathparser.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathparser.h
new file mode 100644
index 0000000..4b2243f
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathparser.h
@@ -0,0 +1,2777 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathparser
+#define headerfilettmathparser
+
+/*!
+ \file ttmathparser.h
+ \brief A mathematical parser
+*/
+
+#include <cstdio>
+#include <vector>
+#include <map>
+#include <set>
+
+#include "ttmath.h"
+#include "ttmathobjects.h"
+#include "ttmathmisc.h"
+
+
+
+namespace ttmath
+{
+
+/*!
+ \brief Mathematical parser
+
+ let x will be an input string meaning an expression for converting:
+
+ x = [+|-]Value[operator[+|-]Value][operator[+|-]Value]...
+ where:
+ an operator can be:
+ ^ (pow) (the heighest priority)
+
+ * (mul) (or multiplication without an operator -- short mul)
+ / (div) (* and / have the same priority)
+
+ + (add)
+ - (sub) (+ and - have the same priority)
+
+ < (lower than)
+ > (greater than)
+ <= (lower or equal than)
+ >= (greater or equal than)
+ == (equal)
+ != (not equal) (all above logical operators have the same priority)
+
+ && (logical and)
+
+ || (logical or) (the lowest priority)
+
+ short mul:
+ if the second Value (Var below) is either a variable or function there might not be
+ an operator between them, e.g.
+ "[+|-]Value Var" is treated as "[+|-]Value * Var" and the multiplication
+ has the same priority as a normal multiplication:
+ 4x = 4 * x
+ 2^3m = (2^3)* m
+ 6h^3 = 6 * (h^3)
+ 2sin(pi) = 2 * sin(pi)
+ etc.
+
+ Value can be:
+ constant e.g. 100, can be preceded by operators for changing the base (radix): [#|&]
+ # - hex
+ & - bin
+ sample: #10 = 16
+ &10 = 2
+ variable e.g. pi
+ another expression between brackets e.g (x)
+ function e.g. sin(x)
+
+ for example a correct input string can be:
+ "1"
+ "2.1234"
+ "2,1234" (they are the same, by default we can either use a comma or a dot)
+ "1 + 2"
+ "(1 + 2) * 3"
+ "pi"
+ "sin(pi)"
+ "(1+2)*(2+3)"
+ "log(2;1234)" there's a semicolon here (not a comma), we use it in functions
+ for separating parameters
+ "1 < 2" (the result will be: 1)
+ "4 < 3" (the result will be: 0)
+ "2+x" (of course if the variable 'x' is defined)
+ "4x+10"
+ "#20+10" = 32 + 10 = 42
+ "10 ^ -&101" = 10 ^ -5 = 0.00001
+ "8 * -&10" = 8 * -2 = -16
+ etc.
+
+ we can also use a semicolon for separating any 'x' input strings
+ for example:
+ "1+2;4+5"
+ the result will be on the stack as follows:
+ stack[0].value=3
+ stack[1].value=9
+*/
+template<class ValueType>
+class Parser
+{
+private:
+
+/*!
+ there are 5 mathematical operators as follows (with their standard priorities):
+ add (+)
+ sub (-)
+ mul (*)
+ div (/)
+ pow (^)
+ and 'shortmul' used when there is no any operators between
+ a first parameter and a variable or function
+ (the 'shortmul' has the same priority as the normal multiplication )
+*/
+ class MatOperator
+ {
+ public:
+
+ enum Type
+ {
+ none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
+ };
+
+ enum Assoc
+ {
+ right, // right-associative
+ non_right // associative or left-associative
+ };
+
+ Type GetType() const { return type; }
+ int GetPriority() const { return priority; }
+ Assoc GetAssoc() const { return assoc; }
+
+ void SetType(Type t)
+ {
+ type = t;
+ assoc = non_right;
+
+ switch( type )
+ {
+ case lor:
+ priority = 4;
+ break;
+
+ case land:
+ priority = 5;
+ break;
+
+ case eq:
+ case neq:
+ case lt:
+ case gt:
+ case let:
+ case get:
+ priority = 7;
+ break;
+
+ case add:
+ case sub:
+ priority = 10;
+ break;
+
+ case mul:
+ case shortmul:
+ case div:
+ priority = 12;
+ break;
+
+ case pow:
+ priority = 14;
+ assoc = right;
+ break;
+
+ default:
+ Error( err_internal_error );
+ break;
+ }
+ }
+
+ MatOperator(): type(none), priority(0), assoc(non_right)
+ {
+ }
+
+ private:
+
+ Type type;
+ int priority;
+ Assoc assoc;
+ }; // end of MatOperator class
+
+
+
+public:
+
+
+
+ /*!
+ Objects of type 'Item' we are keeping on our stack
+ */
+ struct Item
+ {
+ enum Type
+ {
+ none, numerical_value, mat_operator, first_bracket,
+ last_bracket, variable, semicolon
+ };
+
+ // The kind of type which we're keeping
+ Type type;
+
+ // if type == numerical_value
+ ValueType value;
+
+ // if type == mat_operator
+ MatOperator moperator;
+
+ /*
+ if type == first_bracket
+
+ if 'function' is set to true it means that the first recognized bracket
+ was the bracket from function in other words we must call a function when
+ we'll find the 'last' bracket
+ */
+ bool function;
+
+ // if function is true
+ std::string function_name;
+
+ /*
+ the sign of value
+
+ it can be for type==numerical_value or type==first_bracket
+ when it's true it means e.g. that value is equal -value
+ */
+ bool sign;
+
+ Item(): type(none), function(false), sign(false)
+ {
+ }
+
+ }; // end of Item struct
+
+
+/*!
+ stack on which we're keeping the Items
+
+ at the end of parsing we'll have the result here
+ the result don't have to be one value, it can be
+ more than one if we have used a semicolon in the global space
+ e.g. such input string "1+2;3+4" will generate a result:
+ stack[0].value=3
+ stack[1].value=7
+
+ you should check if the stack is not empty, because if there was
+ a syntax error in the input string then we do not have any results
+ on the stack
+*/
+std::vector<Item> stack;
+
+
+private:
+
+
+/*!
+ size of the stack when we're starting parsing of the string
+
+ if it's to small while parsing the stack will be automatically resized
+*/
+const int default_stack_size;
+
+
+
+/*!
+ index of an object in our stack
+ it's pointing on the place behind the last element
+ for example at the beginning of parsing its value is zero
+*/
+unsigned int stack_index;
+
+
+/*!
+ code of the last error
+*/
+ErrorCode error;
+
+
+/*!
+ pointer to the currently reading char
+ when an error has occurred it may be used to count the index of the wrong character
+*/
+const char * pstring;
+
+
+/*!
+ the base (radix) of the mathematic system (for example it may be '10')
+*/
+int base;
+
+
+/*!
+ the unit of angles used in: sin,cos,tan,cot,asin,acos,atan,acot
+ 0 - deg
+ 1 - rad (default)
+ 2 - grad
+*/
+int deg_rad_grad;
+
+
+
+/*!
+ a pointer to an object which tell us whether we should stop calculating or not
+*/
+const volatile StopCalculating * pstop_calculating;
+
+
+
+/*!
+ a pointer to the user-defined variables' table
+*/
+const Objects * puser_variables;
+
+/*!
+ a pointer to the user-defined functions' table
+*/
+const Objects * puser_functions;
+
+
+typedef std::map<std::string, ValueType> FunctionLocalVariables;
+
+/*!
+ a pointer to the local variables of a function
+*/
+const FunctionLocalVariables * pfunction_local_variables;
+
+
+/*!
+ a temporary set using during parsing user defined variables
+*/
+std::set<std::string> visited_variables;
+
+
+/*!
+ a temporary set using during parsing user defined functions
+*/
+std::set<std::string> visited_functions;
+
+
+
+
+/*!
+ pfunction is the type of pointer to a mathematic function
+
+ these mathematic functions are private members of this class,
+ they are the wrappers for standard mathematics function
+
+ 'pstack' is the pointer to the first argument on our stack
+ 'amount_of_arg' tell us how many argument there are in our stack
+ 'result' is the reference for result of function
+*/
+typedef void (Parser<ValueType>::*pfunction)(int pstack, int amount_of_arg, ValueType & result);
+
+
+/*!
+ pfunction is the type of pointer to a method which returns value of variable
+*/
+typedef void (ValueType::*pfunction_var)();
+
+
+/*!
+ table of mathematic functions
+
+ this map consists of:
+ std::string - function's name
+ pfunction - pointer to specific function
+*/
+typedef std::map<std::string, pfunction> FunctionsTable;
+FunctionsTable functions_table;
+
+
+/*!
+ table of mathematic operators
+
+ this map consists of:
+ std::string - operators's name
+ MatOperator::Type - type of the operator
+*/
+typedef std::map<std::string, typename MatOperator::Type> OperatorsTable;
+OperatorsTable operators_table;
+
+
+/*!
+ table of mathematic variables
+
+ this map consists of:
+ std::string - variable's name
+ pfunction_var - pointer to specific function which returns value of variable
+*/
+typedef std::map<std::string, pfunction_var> VariablesTable;
+VariablesTable variables_table;
+
+
+/*!
+ some coefficients used when calculating the gamma (or factorial) function
+*/
+CGamma<ValueType> cgamma;
+
+
+/*!
+ temporary object for a whole string when Parse(std::wstring) is used
+*/
+std::string wide_to_ansi;
+
+
+/*!
+ group character (used when parsing)
+ default zero (not used)
+*/
+int group;
+
+
+/*!
+ characters used as a comma
+ default: '.' and ','
+ comma2 can be zero (it means it is not used)
+*/
+int comma, comma2;
+
+
+/*!
+ an additional character used as a separator between function parameters
+ (semicolon is used always)
+*/
+int param_sep;
+
+
+/*!
+ true if something was calculated (at least one mathematical operator was used or a function or a variable)
+*/
+bool calculated;
+
+
+
+/*!
+ we're using this method for reporting an error
+*/
+static void Error(ErrorCode code)
+{
+ throw code;
+}
+
+
+/*!
+ this method skips the white character from the string
+
+ it's moving the 'pstring' to the first no-white character
+*/
+void SkipWhiteCharacters()
+{
+ while( (*pstring==' ' ) || (*pstring=='\t') )
+ ++pstring;
+}
+
+
+/*!
+ an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
+*/
+void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
+{
+ if( variable )
+ {
+ if( visited_variables.find(name) != visited_variables.end() )
+ Error( err_variable_loop );
+ }
+ else
+ {
+ if( visited_functions.find(name) != visited_functions.end() )
+ Error( err_functions_loop );
+ }
+}
+
+
+/*!
+ an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
+*/
+void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
+{
+ if( variable )
+ visited_variables.insert( name );
+ else
+ visited_functions.insert( name );
+}
+
+
+/*!
+ an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
+*/
+void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
+{
+ if( variable )
+ visited_variables.erase( name );
+ else
+ visited_functions.erase( name );
+}
+
+
+/*!
+ this method returns the value of a variable or function
+ by creating a new instance of the mathematical parser
+ and making the standard parsing algorithm on the given string
+
+ this method is used only during parsing user defined variables or functions
+
+ (there can be a recurrence here therefore we're using 'visited_variables'
+ and 'visited_functions' sets to make a stop condition)
+*/
+ValueType RecurrenceParsingVariablesOrFunction(bool variable, const std::string & name, const char * new_string,
+ FunctionLocalVariables * local_variables = 0)
+{
+ RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
+ RecurrenceParsingVariablesOrFunction_AddName(variable, name);
+
+ Parser<ValueType> NewParser(*this);
+ ErrorCode err;
+
+ NewParser.pfunction_local_variables = local_variables;
+
+ try
+ {
+ err = NewParser.Parse(new_string);
+ }
+ catch(...)
+ {
+ RecurrenceParsingVariablesOrFunction_DeleteName(variable, name);
+
+ throw;
+ }
+
+ RecurrenceParsingVariablesOrFunction_DeleteName(variable, name);
+
+ if( err != err_ok )
+ Error( err );
+
+ if( NewParser.stack.size() != 1 )
+ Error( err_must_be_only_one_value );
+
+ if( NewParser.stack[0].type != Item::numerical_value )
+ // I think there shouldn't be this error here
+ Error( err_incorrect_value );
+
+return NewParser.stack[0].value;
+}
+
+
+public:
+
+
+/*!
+ this method returns the user-defined value of a variable
+*/
+bool GetValueOfUserDefinedVariable(const std::string & variable_name,ValueType & result)
+{
+ if( !puser_variables )
+ return false;
+
+ const char * string_value;
+
+ if( puser_variables->GetValue(variable_name, &string_value) != err_ok )
+ return false;
+
+ result = RecurrenceParsingVariablesOrFunction(true, variable_name, string_value);
+ calculated = true;
+
+return true;
+}
+
+
+/*!
+ this method returns the value of a local variable of a function
+*/
+bool GetValueOfFunctionLocalVariable(const std::string & variable_name, ValueType & result)
+{
+ if( !pfunction_local_variables )
+ return false;
+
+ typename FunctionLocalVariables::const_iterator i = pfunction_local_variables->find(variable_name);
+
+ if( i == pfunction_local_variables->end() )
+ return false;
+
+ result = i->second;
+
+return true;
+}
+
+
+/*!
+ this method returns the value of a variable from variables' table
+
+ we make an object of type ValueType then call a method which
+ sets the correct value in it and finally we'll return the object
+*/
+ValueType GetValueOfVariable(const std::string & variable_name)
+{
+ValueType result;
+
+ if( GetValueOfFunctionLocalVariable(variable_name, result) )
+ return result;
+
+ if( GetValueOfUserDefinedVariable(variable_name, result) )
+ return result;
+
+
+ typename std::map<std::string, pfunction_var>::iterator i =
+ variables_table.find(variable_name);
+
+ if( i == variables_table.end() )
+ Error( err_unknown_variable );
+
+ (result.*(i->second))();
+ calculated = true;
+
+return result;
+}
+
+
+private:
+
+/*!
+ wrappers for mathematic functions
+
+ 'sindex' is pointing on the first argument on our stack
+ (the second argument has 'sindex+2'
+ because 'sindex+1' is guaranted for the 'semicolon' operator)
+ the third artument has of course 'sindex+4' etc.
+
+ 'result' will be the result of the function
+
+ (we're using exceptions here for example when function gets an improper argument)
+*/
+
+
+/*!
+ used by: sin,cos,tan,cot
+*/
+ValueType ConvertAngleToRad(const ValueType & input)
+{
+ if( deg_rad_grad == 1 ) // rad
+ return input;
+
+ ValueType result;
+ ErrorCode err;
+
+ if( deg_rad_grad == 0 ) // deg
+ result = ttmath::DegToRad(input, &err);
+ else // grad
+ result = ttmath::GradToRad(input, &err);
+
+ if( err != err_ok )
+ Error( err );
+
+return result;
+}
+
+
+/*!
+ used by: asin,acos,atan,acot
+*/
+ValueType ConvertRadToAngle(const ValueType & input)
+{
+ if( deg_rad_grad == 1 ) // rad
+ return input;
+
+ ValueType result;
+ ErrorCode err;
+
+ if( deg_rad_grad == 0 ) // deg
+ result = ttmath::RadToDeg(input, &err);
+ else // grad
+ result = ttmath::RadToGrad(input, &err);
+
+ if( err != err_ok )
+ Error( err );
+
+return result;
+}
+
+
+void Gamma(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+
+ result = ttmath::Gamma(stack[sindex].value, cgamma, &err, pstop_calculating);
+
+ if(err != err_ok)
+ Error( err );
+}
+
+
+/*!
+ factorial
+ result = 1 * 2 * 3 * 4 * .... * x
+*/
+void Factorial(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+
+ result = ttmath::Factorial(stack[sindex].value, cgamma, &err, pstop_calculating);
+
+ if(err != err_ok)
+ Error( err );
+}
+
+
+void Abs(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ttmath::Abs(stack[sindex].value);
+}
+
+void Sin(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Sin( ConvertAngleToRad(stack[sindex].value), &err );
+
+ if(err != err_ok)
+ Error( err );
+}
+
+void Cos(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Cos( ConvertAngleToRad(stack[sindex].value), &err );
+
+ if(err != err_ok)
+ Error( err );
+}
+
+void Tan(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Tan(ConvertAngleToRad(stack[sindex].value), &err);
+
+ if(err != err_ok)
+ Error( err );
+}
+
+void Cot(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Cot(ConvertAngleToRad(stack[sindex].value), &err);
+
+ if(err != err_ok)
+ Error( err );
+}
+
+void Int(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ttmath::SkipFraction(stack[sindex].value);
+}
+
+
+void Round(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = stack[sindex].value;
+
+ if( result.Round() )
+ Error( err_overflow );
+}
+
+
+void Ln(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Ln(stack[sindex].value, &err);
+
+ if(err != err_ok)
+ Error( err );
+}
+
+void Log(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 2 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Log(stack[sindex].value, stack[sindex+2].value, &err);
+
+ if(err != err_ok)
+ Error( err );
+}
+
+void Exp(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Exp(stack[sindex].value, &err);
+
+ if(err != err_ok)
+ Error( err );
+}
+
+
+void Max(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args == 0 )
+ {
+ result.SetMax();
+
+ return;
+ }
+
+ result = stack[sindex].value;
+
+ for(int i=1 ; i<amount_of_args ; ++i)
+ {
+ if( result < stack[sindex + i*2].value )
+ result = stack[sindex + i*2].value;
+ }
+}
+
+
+void Min(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args == 0 )
+ {
+ result.SetMin();
+
+ return;
+ }
+
+ result = stack[sindex].value;
+
+ for(int i=1 ; i<amount_of_args ; ++i)
+ {
+ if( result > stack[sindex + i*2].value )
+ result = stack[sindex + i*2].value;
+ }
+}
+
+
+void ASin(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ ValueType temp = ttmath::ASin(stack[sindex].value, &err);
+
+ if(err != err_ok)
+ Error( err );
+
+ result = ConvertRadToAngle(temp);
+}
+
+
+void ACos(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ ValueType temp = ttmath::ACos(stack[sindex].value, &err);
+
+ if(err != err_ok)
+ Error( err );
+
+ result = ConvertRadToAngle(temp);
+}
+
+
+void ATan(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ConvertRadToAngle(ttmath::ATan(stack[sindex].value));
+}
+
+
+void ACot(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ConvertRadToAngle(ttmath::ACot(stack[sindex].value));
+}
+
+
+void Sgn(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ttmath::Sgn(stack[sindex].value);
+}
+
+
+void Mod(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 2 )
+ Error( err_improper_amount_of_arguments );
+
+ if( stack[sindex+2].value.IsZero() )
+ Error( err_improper_argument );
+
+ result = stack[sindex].value;
+ uint c = result.Mod(stack[sindex+2].value);
+
+ if( c )
+ Error( err_overflow );
+}
+
+
+void If(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 3 )
+ Error( err_improper_amount_of_arguments );
+
+
+ if( !stack[sindex].value.IsZero() )
+ result = stack[sindex+2].value;
+ else
+ result = stack[sindex+4].value;
+}
+
+
+void Or(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args < 2 )
+ Error( err_improper_amount_of_arguments );
+
+ for(int i=0 ; i<amount_of_args ; ++i)
+ {
+ if( !stack[sindex+i*2].value.IsZero() )
+ {
+ result.SetOne();
+ return;
+ }
+ }
+
+ result.SetZero();
+}
+
+
+void And(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args < 2 )
+ Error( err_improper_amount_of_arguments );
+
+ for(int i=0 ; i<amount_of_args ; ++i)
+ {
+ if( stack[sindex+i*2].value.IsZero() )
+ {
+ result.SetZero();
+ return;
+ }
+ }
+
+ result.SetOne();
+}
+
+
+void Not(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+
+ if( stack[sindex].value.IsZero() )
+ result.SetOne();
+ else
+ result.SetZero();
+}
+
+
+void DegToRad(int sindex, int amount_of_args, ValueType & result)
+{
+ ErrorCode err = err_ok;
+
+ if( amount_of_args == 1 )
+ {
+ result = ttmath::DegToRad(stack[sindex].value, &err);
+ }
+ else
+ if( amount_of_args == 3 )
+ {
+ result = ttmath::DegToRad( stack[sindex].value, stack[sindex+2].value,
+ stack[sindex+4].value, &err);
+ }
+ else
+ Error( err_improper_amount_of_arguments );
+
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void RadToDeg(int sindex, int amount_of_args, ValueType & result)
+{
+ ErrorCode err;
+
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ttmath::RadToDeg(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void DegToDeg(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 3 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::DegToDeg( stack[sindex].value, stack[sindex+2].value,
+ stack[sindex+4].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void GradToRad(int sindex, int amount_of_args, ValueType & result)
+{
+ ErrorCode err;
+
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ttmath::GradToRad(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void RadToGrad(int sindex, int amount_of_args, ValueType & result)
+{
+ ErrorCode err;
+
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ttmath::RadToGrad(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void DegToGrad(int sindex, int amount_of_args, ValueType & result)
+{
+ ErrorCode err = err_ok;
+
+ if( amount_of_args == 1 )
+ {
+ result = ttmath::DegToGrad(stack[sindex].value, &err);
+ }
+ else
+ if( amount_of_args == 3 )
+ {
+ result = ttmath::DegToGrad( stack[sindex].value, stack[sindex+2].value,
+ stack[sindex+4].value, &err);
+ }
+ else
+ Error( err_improper_amount_of_arguments );
+
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void GradToDeg(int sindex, int amount_of_args, ValueType & result)
+{
+ ErrorCode err;
+
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = ttmath::GradToDeg(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void Ceil(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Ceil(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void Floor(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Floor(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+void Sqrt(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Sqrt(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void Sinh(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Sinh(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void Cosh(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Cosh(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void Tanh(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Tanh(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void Coth(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Coth(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void Root(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 2 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::Root(stack[sindex].value, stack[sindex+2].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+
+void ASinh(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::ASinh(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void ACosh(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::ACosh(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void ATanh(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::ATanh(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void ACoth(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ ErrorCode err;
+ result = ttmath::ACoth(stack[sindex].value, &err);
+
+ if( err != err_ok )
+ Error( err );
+}
+
+
+void BitAnd(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 2 )
+ Error( err_improper_amount_of_arguments );
+
+ uint err;
+ result = stack[sindex].value;
+ err = result.BitAnd(stack[sindex+2].value);
+
+ switch(err)
+ {
+ case 1:
+ Error( err_overflow );
+ break;
+ case 2:
+ Error( err_improper_argument );
+ break;
+ }
+}
+
+void BitOr(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 2 )
+ Error( err_improper_amount_of_arguments );
+
+ uint err;
+ result = stack[sindex].value;
+ err = result.BitOr(stack[sindex+2].value);
+
+ switch(err)
+ {
+ case 1:
+ Error( err_overflow );
+ break;
+ case 2:
+ Error( err_improper_argument );
+ break;
+ }
+}
+
+
+void BitXor(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 2 )
+ Error( err_improper_amount_of_arguments );
+
+ uint err;
+ result = stack[sindex].value;
+ err = result.BitXor(stack[sindex+2].value);
+
+ switch(err)
+ {
+ case 1:
+ Error( err_overflow );
+ break;
+ case 2:
+ Error( err_improper_argument );
+ break;
+ }
+}
+
+
+void Sum(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args == 0 )
+ Error( err_improper_amount_of_arguments );
+
+ result = stack[sindex].value;
+
+ for(int i=1 ; i<amount_of_args ; ++i )
+ if( result.Add( stack[ sindex + i*2 ].value ) )
+ Error( err_overflow );
+}
+
+void Avg(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args == 0 )
+ Error( err_improper_amount_of_arguments );
+
+ result = stack[sindex].value;
+
+ for(int i=1 ; i<amount_of_args ; ++i )
+ if( result.Add( stack[ sindex + i*2 ].value ) )
+ Error( err_overflow );
+
+ if( result.Div( amount_of_args ) )
+ Error( err_overflow );
+}
+
+
+void Frac(int sindex, int amount_of_args, ValueType & result)
+{
+ if( amount_of_args != 1 )
+ Error( err_improper_amount_of_arguments );
+
+ result = stack[sindex].value;
+ result.RemainFraction();
+}
+
+
+
+
+/*!
+ we use such a method because 'wvsprintf' is not everywhere defined
+*/
+void Sprintf(char * buffer, int par)
+{
+char buf[30]; // char, not wchar_t
+int i;
+
+ #ifdef _MSC_VER
+ #pragma warning( disable: 4996 )
+ //warning C4996: 'sprintf': This function or variable may be unsafe.
+ #endif
+
+ sprintf(buf, "%d", par);
+ for(i=0 ; buf[i] != 0 ; ++i)
+ buffer[i] = buf[i];
+
+ buffer[i] = 0;
+
+ #ifdef _MSC_VER
+ #pragma warning( default: 4996 )
+ #endif
+}
+
+
+
+
+/*!
+ this method returns the value from a user-defined function
+
+ (look at the description in 'CallFunction(...)')
+*/
+bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount_of_args, int sindex)
+{
+ if( !puser_functions )
+ return false;
+
+ const char * string_value;
+ int param;
+
+ if( puser_functions->GetValueAndParam(function_name, &string_value, ¶m) != err_ok )
+ return false;
+
+ if( param != amount_of_args )
+ Error( err_improper_amount_of_arguments );
+
+
+ FunctionLocalVariables local_variables;
+
+ if( amount_of_args > 0 )
+ {
+ char buffer[30];
+
+ // x = x1
+ buffer[0] = 'x';
+ buffer[1] = 0;
+ local_variables.insert( std::make_pair(buffer, stack[sindex].value) );
+
+ for(int i=0 ; i<amount_of_args ; ++i)
+ {
+ buffer[0] = 'x';
+ Sprintf(buffer+1, i+1);
+ local_variables.insert( std::make_pair(buffer, stack[sindex + i*2].value) );
+ }
+ }
+
+ stack[sindex-1].value = RecurrenceParsingVariablesOrFunction(false, function_name, string_value, &local_variables);
+ calculated = true;
+
+return true;
+}
+
+
+/*
+ we're calling a specific function
+
+ function_name - name of the function
+ amount_of_args - how many arguments there are on our stack
+ (function must check whether this is a correct value or not)
+ sindex - index of the first argument on the stack (sindex is greater than zero)
+ if there aren't any arguments on the stack 'sindex' pointing on
+ a non existend element (after the first bracket)
+
+ result will be stored in 'stack[sindex-1].value'
+ (we don't have to set the correct type of this element, it'll be set later)
+*/
+void CallFunction(const std::string & function_name, int amount_of_args, int sindex)
+{
+ if( GetValueOfUserDefinedFunction(function_name, amount_of_args, sindex) )
+ return;
+
+ typename FunctionsTable::iterator i = functions_table.find( function_name );
+
+ if( i == functions_table.end() )
+ Error( err_unknown_function );
+
+ /*
+ calling the specify function
+ */
+ (this->*(i->second))(sindex, amount_of_args, stack[sindex-1].value);
+ calculated = true;
+}
+
+
+
+
+
+/*!
+ inserting a function to the functions' table
+
+ function_name - name of the function
+ pf - pointer to the function (to the wrapper)
+*/
+void InsertFunctionToTable(const char * function_name, pfunction pf)
+{
+ std::string str;
+ Misc::AssignString(str, function_name);
+
+ functions_table.insert( std::make_pair(str, pf) );
+}
+
+
+
+/*!
+ inserting a function to the variables' table
+ (this function returns value of variable)
+
+ variable_name - name of the function
+ pf - pointer to the function
+*/
+void InsertVariableToTable(const char * variable_name, pfunction_var pf)
+{
+ std::string str;
+ Misc::AssignString(str, variable_name);
+
+ variables_table.insert( std::make_pair(str, pf) );
+}
+
+
+/*!
+ this method creates the table of functions
+*/
+void CreateFunctionsTable()
+{
+ InsertFunctionToTable("gamma", &Parser<ValueType>::Gamma);
+ InsertFunctionToTable("factorial", &Parser<ValueType>::Factorial);
+ InsertFunctionToTable("abs", &Parser<ValueType>::Abs);
+ InsertFunctionToTable("sin", &Parser<ValueType>::Sin);
+ InsertFunctionToTable("cos", &Parser<ValueType>::Cos);
+ InsertFunctionToTable("tan", &Parser<ValueType>::Tan);
+ InsertFunctionToTable("tg", &Parser<ValueType>::Tan);
+ InsertFunctionToTable("cot", &Parser<ValueType>::Cot);
+ InsertFunctionToTable("ctg", &Parser<ValueType>::Cot);
+ InsertFunctionToTable("int", &Parser<ValueType>::Int);
+ InsertFunctionToTable("round", &Parser<ValueType>::Round);
+ InsertFunctionToTable("ln", &Parser<ValueType>::Ln);
+ InsertFunctionToTable("log", &Parser<ValueType>::Log);
+ InsertFunctionToTable("exp", &Parser<ValueType>::Exp);
+ InsertFunctionToTable("max", &Parser<ValueType>::Max);
+ InsertFunctionToTable("min", &Parser<ValueType>::Min);
+ InsertFunctionToTable("asin", &Parser<ValueType>::ASin);
+ InsertFunctionToTable("acos", &Parser<ValueType>::ACos);
+ InsertFunctionToTable("atan", &Parser<ValueType>::ATan);
+ InsertFunctionToTable("atg", &Parser<ValueType>::ATan);
+ InsertFunctionToTable("acot", &Parser<ValueType>::ACot);
+ InsertFunctionToTable("actg", &Parser<ValueType>::ACot);
+ InsertFunctionToTable("sgn", &Parser<ValueType>::Sgn);
+ InsertFunctionToTable("mod", &Parser<ValueType>::Mod);
+ InsertFunctionToTable("if", &Parser<ValueType>::If);
+ InsertFunctionToTable("or", &Parser<ValueType>::Or);
+ InsertFunctionToTable("and", &Parser<ValueType>::And);
+ InsertFunctionToTable("not", &Parser<ValueType>::Not);
+ InsertFunctionToTable("degtorad", &Parser<ValueType>::DegToRad);
+ InsertFunctionToTable("radtodeg", &Parser<ValueType>::RadToDeg);
+ InsertFunctionToTable("degtodeg", &Parser<ValueType>::DegToDeg);
+ InsertFunctionToTable("gradtorad", &Parser<ValueType>::GradToRad);
+ InsertFunctionToTable("radtograd", &Parser<ValueType>::RadToGrad);
+ InsertFunctionToTable("degtograd", &Parser<ValueType>::DegToGrad);
+ InsertFunctionToTable("gradtodeg", &Parser<ValueType>::GradToDeg);
+ InsertFunctionToTable("ceil", &Parser<ValueType>::Ceil);
+ InsertFunctionToTable("floor", &Parser<ValueType>::Floor);
+ InsertFunctionToTable("sqrt", &Parser<ValueType>::Sqrt);
+ InsertFunctionToTable("sinh", &Parser<ValueType>::Sinh);
+ InsertFunctionToTable("cosh", &Parser<ValueType>::Cosh);
+ InsertFunctionToTable("tanh", &Parser<ValueType>::Tanh);
+ InsertFunctionToTable("tgh", &Parser<ValueType>::Tanh);
+ InsertFunctionToTable("coth", &Parser<ValueType>::Coth);
+ InsertFunctionToTable("ctgh", &Parser<ValueType>::Coth);
+ InsertFunctionToTable("root", &Parser<ValueType>::Root);
+ InsertFunctionToTable("asinh", &Parser<ValueType>::ASinh);
+ InsertFunctionToTable("acosh", &Parser<ValueType>::ACosh);
+ InsertFunctionToTable("atanh", &Parser<ValueType>::ATanh);
+ InsertFunctionToTable("atgh", &Parser<ValueType>::ATanh);
+ InsertFunctionToTable("acoth", &Parser<ValueType>::ACoth);
+ InsertFunctionToTable("actgh", &Parser<ValueType>::ACoth);
+ InsertFunctionToTable("bitand", &Parser<ValueType>::BitAnd);
+ InsertFunctionToTable("bitor", &Parser<ValueType>::BitOr);
+ InsertFunctionToTable("bitxor", &Parser<ValueType>::BitXor);
+ InsertFunctionToTable("band", &Parser<ValueType>::BitAnd);
+ InsertFunctionToTable("bor", &Parser<ValueType>::BitOr);
+ InsertFunctionToTable("bxor", &Parser<ValueType>::BitXor);
+ InsertFunctionToTable("sum", &Parser<ValueType>::Sum);
+ InsertFunctionToTable("avg", &Parser<ValueType>::Avg);
+ InsertFunctionToTable("frac", &Parser<ValueType>::Frac);
+}
+
+
+/*!
+ this method creates the table of variables
+*/
+void CreateVariablesTable()
+{
+ InsertVariableToTable("pi", &ValueType::SetPi);
+ InsertVariableToTable("e", &ValueType::SetE);
+}
+
+
+/*!
+ converting from a big letter to a small one
+*/
+int ToLowerCase(int c)
+{
+ if( c>='A' && c<='Z' )
+ return c - 'A' + 'a';
+
+return c;
+}
+
+
+/*!
+ this method read the name of a variable or a function
+
+ 'result' will be the name of a variable or a function
+ function return 'false' if this name is the name of a variable
+ or function return 'true' if this name is the name of a function
+
+ what should be returned is tested just by a '(' character that means if there's
+ a '(' character after a name that function returns 'true'
+*/
+bool ReadName(std::string & result)
+{
+int character;
+
+
+ result.erase();
+ character = *pstring;
+
+ /*
+ the first letter must be from range 'a' - 'z' or 'A' - 'Z'
+ */
+ if( ! (( character>='a' && character<='z' ) || ( character>='A' && character<='Z' )) )
+ Error( err_unknown_character );
+
+
+ do
+ {
+ result += static_cast<char>( character );
+ character = * ++pstring;
+ }
+ while( (character>='a' && character<='z') ||
+ (character>='A' && character<='Z') ||
+ (character>='0' && character<='9') ||
+ character=='_' );
+
+
+ SkipWhiteCharacters();
+
+
+ /*
+ if there's a character '(' that means this name is a name of a function
+ */
+ if( *pstring == '(' )
+ {
+ ++pstring;
+ return true;
+ }
+
+
+return false;
+}
+
+
+/*!
+ we're checking whether the first character is '-' or '+'
+ if it is we'll return 'true' and if it is equally '-' we'll set the 'sign' member of 'result'
+*/
+bool TestSign(Item & result)
+{
+ SkipWhiteCharacters();
+ result.sign = false;
+
+ if( *pstring == '-' || *pstring == '+' )
+ {
+ if( *pstring == '-' )
+ result.sign = true;
+
+ ++pstring;
+
+ return true;
+ }
+
+return false;
+}
+
+
+/*!
+ we're reading the name of a variable or a function
+ if is there a function we'll return 'true'
+*/
+bool ReadVariableOrFunction(Item & result)
+{
+std::string name;
+bool is_it_name_of_function = ReadName(name);
+
+ if( is_it_name_of_function )
+ {
+ /*
+ we've read the name of a function
+ */
+ result.function_name = name;
+ result.type = Item::first_bracket;
+ result.function = true;
+ }
+ else
+ {
+ /*
+ we've read the name of a variable and we're getting its value now
+ */
+ result.value = GetValueOfVariable( name );
+ }
+
+return is_it_name_of_function;
+}
+
+
+
+
+/*!
+ we're reading a numerical value directly from the string
+*/
+void ReadValue(Item & result, int reading_base)
+{
+const char * new_stack_pointer;
+bool value_read;
+Conv conv;
+
+ conv.base = reading_base;
+ conv.comma = comma;
+ conv.comma2 = comma2;
+ conv.group = group;
+
+ uint carry = result.value.FromString(pstring, conv, &new_stack_pointer, &value_read);
+ pstring = new_stack_pointer;
+
+ if( carry )
+ Error( err_overflow );
+
+ if( !value_read )
+ Error( err_unknown_character );
+}
+
+
+/*!
+ this method returns true if 'character' is a proper first digit for the value (or a comma -- can be first too)
+*/
+bool ValueStarts(int character, int base)
+{
+ if( character == comma )
+ return true;
+
+ if( comma2!=0 && character==comma2 )
+ return true;
+
+ if( Misc::CharToDigit(character, base) != -1 )
+ return true;
+
+return false;
+}
+
+
+/*!
+ we're reading the item
+
+ return values:
+ 0 - all ok, the item is successfully read
+ 1 - the end of the string (the item is not read)
+ 2 - the final bracket ')'
+*/
+int ReadValueVariableOrFunction(Item & result)
+{
+bool it_was_sign = false;
+int character;
+
+
+ if( TestSign(result) )
+ // 'result.sign' was set as well
+ it_was_sign = true;
+
+ SkipWhiteCharacters();
+ character = ToLowerCase( *pstring );
+
+
+ if( character == 0 )
+ {
+ if( it_was_sign )
+ // at the end of the string a character like '-' or '+' has left
+ Error( err_unexpected_end );
+
+ // there's the end of the string here
+ return 1;
+ }
+ else
+ if( character == '(' )
+ {
+ // we've got a normal bracket (not a function)
+ result.type = Item::first_bracket;
+ result.function = false;
+ ++pstring;
+
+ return 0;
+ }
+ else
+ if( character == ')' )
+ {
+ // we've got a final bracket
+ // (in this place we can find a final bracket only when there are empty brackets
+ // without any values inside or with a sign '-' or '+' inside)
+
+ if( it_was_sign )
+ Error( err_unexpected_final_bracket );
+
+ result.type = Item::last_bracket;
+
+ // we don't increment 'pstring', this final bracket will be read next by the
+ // 'ReadOperatorAndCheckFinalBracket(...)' method
+
+ return 2;
+ }
+ else
+ if( character == '#' )
+ {
+ ++pstring;
+ SkipWhiteCharacters();
+
+ // after '#' character we do not allow '-' or '+' (can be white characters)
+ if( ValueStarts(*pstring, 16) )
+ ReadValue( result, 16 );
+ else
+ Error( err_unknown_character );
+ }
+ else
+ if( character == '&' )
+ {
+ ++pstring;
+ SkipWhiteCharacters();
+
+ // after '&' character we do not allow '-' or '+' (can be white characters)
+ if( ValueStarts(*pstring, 2) )
+ ReadValue( result, 2 );
+ else
+ Error( err_unknown_character );
+ }
+ else
+ if( ValueStarts(character, base) )
+ {
+ ReadValue( result, base );
+ }
+ else
+ if( character>='a' && character<='z' )
+ {
+ if( ReadVariableOrFunction(result) )
+ // we've read the name of a function
+ return 0;
+ }
+ else
+ Error( err_unknown_character );
+
+
+
+ /*
+ we've got a value in the 'result'
+ this value is from a variable or directly from the string
+ */
+ result.type = Item::numerical_value;
+
+ if( result.sign )
+ {
+ result.value.ChangeSign();
+ result.sign = false;
+ }
+
+
+return 0;
+}
+
+
+void InsertOperatorToTable(const char * name, typename MatOperator::Type type)
+{
+ operators_table.insert( std::make_pair(std::string(name), type) );
+}
+
+
+/*!
+ this method creates the table of operators
+*/
+void CreateMathematicalOperatorsTable()
+{
+ InsertOperatorToTable("||", MatOperator::lor);
+ InsertOperatorToTable("&&", MatOperator::land);
+ InsertOperatorToTable("!=", MatOperator::neq);
+ InsertOperatorToTable("==", MatOperator::eq);
+ InsertOperatorToTable(">=", MatOperator::get);
+ InsertOperatorToTable("<=", MatOperator::let);
+ InsertOperatorToTable(">", MatOperator::gt);
+ InsertOperatorToTable("<", MatOperator::lt);
+ InsertOperatorToTable("-", MatOperator::sub);
+ InsertOperatorToTable("+", MatOperator::add);
+ InsertOperatorToTable("/", MatOperator::div);
+ InsertOperatorToTable("*", MatOperator::mul);
+ InsertOperatorToTable("^", MatOperator::pow);
+}
+
+
+/*!
+ returns true if 'str2' is the substring of str1
+
+ e.g.
+ true when str1="test" and str2="te"
+*/
+bool IsSubstring(const std::string & str1, const std::string & str2)
+{
+ if( str2.length() > str1.length() )
+ return false;
+
+ for(typename std::string::size_type i=0 ; i<str2.length() ; ++i)
+ if( str1[i] != str2[i] )
+ return false;
+
+return true;
+}
+
+
+/*!
+ this method reads a mathematical (or logical) operator
+*/
+void ReadMathematicalOperator(Item & result)
+{
+std::string oper;
+typename OperatorsTable::iterator iter_old, iter_new;
+
+ iter_old = operators_table.end();
+
+ for( ; true ; ++pstring )
+ {
+ oper += *pstring;
+ iter_new = operators_table.lower_bound(oper);
+
+ if( iter_new == operators_table.end() || !IsSubstring(iter_new->first, oper) )
+ {
+ oper.erase( --oper.end() ); // we've got mininum one element
+
+ if( iter_old != operators_table.end() && iter_old->first == oper )
+ {
+ result.type = Item::mat_operator;
+ result.moperator.SetType( iter_old->second );
+ break;
+ }
+
+ Error( err_unknown_operator );
+ }
+
+ iter_old = iter_new;
+ }
+}
+
+
+/*!
+ this method makes a calculation for the percentage operator
+ e.g.
+ 1000-50% = 1000-(1000*0,5) = 500
+*/
+void OperatorPercentage()
+{
+ if( stack_index < 3 ||
+ stack[stack_index-1].type != Item::numerical_value ||
+ stack[stack_index-2].type != Item::mat_operator ||
+ stack[stack_index-3].type != Item::numerical_value )
+ Error(err_percent_from);
+
+ ++pstring;
+ SkipWhiteCharacters();
+
+ uint c = 0;
+ c += stack[stack_index-1].value.Div(100);
+ c += stack[stack_index-1].value.Mul(stack[stack_index-3].value);
+
+ if( c )
+ Error(err_overflow);
+}
+
+
+/*!
+ this method reads a mathematic operators
+ or the final bracket or the semicolon operator
+
+ return values:
+ 0 - ok
+ 1 - the string is finished
+*/
+int ReadOperator(Item & result)
+{
+ SkipWhiteCharacters();
+
+ if( *pstring == '%' )
+ OperatorPercentage();
+
+
+ if( *pstring == 0 )
+ return 1;
+ else
+ if( *pstring == ')' )
+ {
+ result.type = Item::last_bracket;
+ ++pstring;
+ }
+ else
+ if( *pstring == ';' || (param_sep!=0 && *pstring==param_sep) )
+ {
+ result.type = Item::semicolon;
+ ++pstring;
+ }
+ else
+ if( (*pstring>='a' && *pstring<='z') || (*pstring>='A' && *pstring<='Z') )
+ {
+ // short mul (without any operators)
+
+ result.type = Item::mat_operator;
+ result.moperator.SetType( MatOperator::shortmul );
+ }
+ else
+ ReadMathematicalOperator(result);
+
+return 0;
+}
+
+
+
+/*!
+ this method is making the standard mathematic operation like '-' '+' '*' '/' and '^'
+
+ the operation is made between 'value1' and 'value2'
+ the result of this operation is stored in the 'value1'
+*/
+void MakeStandardMathematicOperation(ValueType & value1, typename MatOperator::Type mat_operator,
+ const ValueType & value2)
+{
+uint res;
+
+ calculated = true;
+
+ switch( mat_operator )
+ {
+ case MatOperator::land:
+ (!value1.IsZero() && !value2.IsZero()) ? value1.SetOne() : value1.SetZero();
+ break;
+
+ case MatOperator::lor:
+ (!value1.IsZero() || !value2.IsZero()) ? value1.SetOne() : value1.SetZero();
+ break;
+
+ case MatOperator::eq:
+ (value1 == value2) ? value1.SetOne() : value1.SetZero();
+ break;
+
+ case MatOperator::neq:
+ (value1 != value2) ? value1.SetOne() : value1.SetZero();
+ break;
+
+ case MatOperator::lt:
+ (value1 < value2) ? value1.SetOne() : value1.SetZero();
+ break;
+
+ case MatOperator::gt:
+ (value1 > value2) ? value1.SetOne() : value1.SetZero();
+ break;
+
+ case MatOperator::let:
+ (value1 <= value2) ? value1.SetOne() : value1.SetZero();
+ break;
+
+ case MatOperator::get:
+ (value1 >= value2) ? value1.SetOne() : value1.SetZero();
+ break;
+
+ case MatOperator::sub:
+ if( value1.Sub(value2) ) Error( err_overflow );
+ break;
+
+ case MatOperator::add:
+ if( value1.Add(value2) ) Error( err_overflow );
+ break;
+
+ case MatOperator::mul:
+ case MatOperator::shortmul:
+ if( value1.Mul(value2) ) Error( err_overflow );
+ break;
+
+ case MatOperator::div:
+ if( value2.IsZero() ) Error( err_division_by_zero );
+ if( value1.Div(value2) ) Error( err_overflow );
+ break;
+
+ case MatOperator::pow:
+ res = value1.Pow( value2 );
+
+ if( res == 1 ) Error( err_overflow );
+ else
+ if( res == 2 ) Error( err_improper_argument );
+
+ break;
+
+ default:
+ /*
+ on the stack left an unknown operator but we had to recognize its before
+ that means there's an error in our algorithm
+ */
+ Error( err_internal_error );
+ }
+}
+
+
+
+
+/*!
+ this method is trying to roll the stack up with the operator's priority
+
+ for example if there are:
+ "1 - 2 +"
+ we can subtract "1-2" and the result store on the place where is '1' and copy the last
+ operator '+', that means there'll be '-1+' on our stack
+
+ but if there are:
+ "1 - 2 *"
+ we can't roll the stack up because the operator '*' has greater priority than '-'
+*/
+void TryRollingUpStackWithOperatorPriority()
+{
+ while( stack_index>=4 &&
+ stack[stack_index-4].type == Item::numerical_value &&
+ stack[stack_index-3].type == Item::mat_operator &&
+ stack[stack_index-2].type == Item::numerical_value &&
+ stack[stack_index-1].type == Item::mat_operator &&
+ (
+ (
+ // the first operator has greater priority
+ stack[stack_index-3].moperator.GetPriority() > stack[stack_index-1].moperator.GetPriority()
+ ) ||
+ (
+ // or both operators have the same priority and the first operator is not right associative
+ stack[stack_index-3].moperator.GetPriority() == stack[stack_index-1].moperator.GetPriority() &&
+ stack[stack_index-3].moperator.GetAssoc() == MatOperator::non_right
+ )
+ )
+ )
+ {
+ MakeStandardMathematicOperation(stack[stack_index-4].value,
+ stack[stack_index-3].moperator.GetType(),
+ stack[stack_index-2].value);
+
+
+ /*
+ copying the last operator and setting the stack pointer to the correct value
+ */
+ stack[stack_index-3] = stack[stack_index-1];
+ stack_index -= 2;
+ }
+}
+
+
+/*!
+ this method is trying to roll the stack up without testing any operators
+
+ for example if there are:
+ "1 - 2"
+ there'll be "-1" on our stack
+*/
+void TryRollingUpStack()
+{
+ while( stack_index >= 3 &&
+ stack[stack_index-3].type == Item::numerical_value &&
+ stack[stack_index-2].type == Item::mat_operator &&
+ stack[stack_index-1].type == Item::numerical_value )
+ {
+ MakeStandardMathematicOperation( stack[stack_index-3].value,
+ stack[stack_index-2].moperator.GetType(),
+ stack[stack_index-1].value );
+
+ stack_index -= 2;
+ }
+}
+
+
+/*!
+ this method is reading a value or a variable or a function
+ (the normal first bracket as well) and push it into the stack
+*/
+int ReadValueVariableOrFunctionAndPushItIntoStack(Item & temp)
+{
+int code = ReadValueVariableOrFunction( temp );
+
+ if( code == 0 )
+ {
+ if( stack_index < stack.size() )
+ stack[stack_index] = temp;
+ else
+ stack.push_back( temp );
+
+ ++stack_index;
+ }
+
+ if( code == 2 )
+ // there was a final bracket, we didn't push it into the stack
+ // (it'll be read by the 'ReadOperatorAndCheckFinalBracket' method next)
+ code = 0;
+
+
+return code;
+}
+
+
+
+/*!
+ this method calculate how many parameters there are on the stack
+ and the index of the first parameter
+
+ if there aren't any parameters on the stack this method returns
+ 'size' equals zero and 'index' pointing after the first bracket
+ (on non-existend element)
+*/
+void HowManyParameters(int & size, int & index)
+{
+ size = 0;
+ index = stack_index;
+
+ if( index == 0 )
+ // we haven't put a first bracket on the stack
+ Error( err_unexpected_final_bracket );
+
+
+ if( stack[index-1].type == Item::first_bracket )
+ // empty brackets
+ return;
+
+ for( --index ; index>=1 ; index-=2 )
+ {
+ if( stack[index].type != Item::numerical_value )
+ {
+ /*
+ this element must be 'numerical_value', if not that means
+ there's an error in our algorithm
+ */
+ Error( err_internal_error );
+ }
+
+ ++size;
+
+ if( stack[index-1].type != Item::semicolon )
+ break;
+ }
+
+ if( index<1 || stack[index-1].type != Item::first_bracket )
+ {
+ /*
+ we haven't put a first bracket on the stack
+ */
+ Error( err_unexpected_final_bracket );
+ }
+}
+
+
+/*!
+ this method is being called when the final bracket ')' is being found
+
+ this method's rolling the stack up, counting how many parameters there are
+ on the stack and if there was a function it's calling the function
+*/
+void RollingUpFinalBracket()
+{
+int amount_of_parameters;
+int index;
+
+
+ if( stack_index<1 ||
+ (stack[stack_index-1].type != Item::numerical_value &&
+ stack[stack_index-1].type != Item::first_bracket)
+ )
+ Error( err_unexpected_final_bracket );
+
+
+ TryRollingUpStack();
+ HowManyParameters(amount_of_parameters, index);
+
+ // 'index' will be greater than zero
+ // 'amount_of_parameters' can be zero
+
+
+ if( amount_of_parameters==0 && !stack[index-1].function )
+ Error( err_unexpected_final_bracket );
+
+
+ bool was_sign = stack[index-1].sign;
+
+
+ if( stack[index-1].function )
+ {
+ // the result of a function will be on 'stack[index-1]'
+ // and then at the end we'll set the correct type (numerical value) of this element
+ CallFunction(stack[index-1].function_name, amount_of_parameters, index);
+ }
+ else
+ {
+ /*
+ there was a normal bracket (not a funcion)
+ */
+ if( amount_of_parameters != 1 )
+ Error( err_unexpected_semicolon_operator );
+
+
+ /*
+ in the place where is the bracket we put the result
+ */
+ stack[index-1] = stack[index];
+ }
+
+
+ /*
+ if there was a '-' character before the first bracket
+ we change the sign of the expression
+ */
+ stack[index-1].sign = false;
+
+ if( was_sign )
+ stack[index-1].value.ChangeSign();
+
+ stack[index-1].type = Item::numerical_value;
+
+
+ /*
+ the pointer of the stack will be pointing on the next (non-existing now) element
+ */
+ stack_index = index;
+}
+
+
+/*!
+ this method is putting the operator on the stack
+*/
+
+void PushOperatorIntoStack(Item & temp)
+{
+ if( stack_index < stack.size() )
+ stack[stack_index] = temp;
+ else
+ stack.push_back( temp );
+
+ ++stack_index;
+}
+
+
+
+/*!
+ this method is reading a operator and if it's a final bracket
+ it's calling RollingUpFinalBracket() and reading a operator again
+*/
+int ReadOperatorAndCheckFinalBracket(Item & temp)
+{
+ do
+ {
+ if( ReadOperator(temp) == 1 )
+ {
+ /*
+ the string is finished
+ */
+ return 1;
+ }
+
+ if( temp.type == Item::last_bracket )
+ RollingUpFinalBracket();
+
+ }
+ while( temp.type == Item::last_bracket );
+
+return 0;
+}
+
+
+/*!
+ we check wheter there are only numerical value's or 'semicolon' operators on the stack
+*/
+void CheckIntegrityOfStack()
+{
+ for(unsigned int i=0 ; i<stack_index; ++i)
+ {
+ if( stack[i].type != Item::numerical_value &&
+ stack[i].type != Item::semicolon)
+ {
+ /*
+ on the stack we must only have 'numerical_value' or 'semicolon' operator
+ if there is something another that means
+ we probably didn't close any of the 'first' bracket
+ */
+ Error( err_stack_not_clear );
+ }
+ }
+}
+
+
+
+/*!
+ the main loop of parsing
+*/
+void Parse()
+{
+Item item;
+int result_code;
+
+
+ while( true )
+ {
+ if( pstop_calculating && pstop_calculating->WasStopSignal() )
+ Error( err_interrupt );
+
+ result_code = ReadValueVariableOrFunctionAndPushItIntoStack( item );
+
+ if( result_code == 0 )
+ {
+ if( item.type == Item::first_bracket )
+ continue;
+
+ result_code = ReadOperatorAndCheckFinalBracket( item );
+ }
+
+
+ if( result_code==1 || item.type==Item::semicolon )
+ {
+ /*
+ the string is finished or the 'semicolon' operator has appeared
+ */
+
+ if( stack_index == 0 )
+ Error( err_nothing_has_read );
+
+ TryRollingUpStack();
+
+ if( result_code == 1 )
+ {
+ CheckIntegrityOfStack();
+
+ return;
+ }
+ }
+
+
+ PushOperatorIntoStack( item );
+ TryRollingUpStackWithOperatorPriority();
+ }
+}
+
+/*!
+ this method is called at the end of the parsing process
+
+ on our stack we can have another value than 'numerical_values' for example
+ when someone use the operator ';' in the global scope or there was an error during
+ parsing and the parser hasn't finished its job
+
+ if there was an error the stack is cleaned up now
+ otherwise we resize stack and leave on it only 'numerical_value' items
+*/
+void NormalizeStack()
+{
+ if( error!=err_ok || stack_index==0 )
+ {
+ stack.clear();
+ return;
+ }
+
+
+ /*
+ 'stack_index' tell us how many elements there are on the stack,
+ we must resize the stack now because 'stack_index' is using only for parsing
+ and stack has more (or equal) elements than value of 'stack_index'
+ */
+ stack.resize( stack_index );
+
+ for(uint i=stack_index-1 ; i!=uint(-1) ; --i)
+ {
+ if( stack[i].type != Item::numerical_value )
+ stack.erase( stack.begin() + i );
+ }
+}
+
+
+public:
+
+
+/*!
+ the default constructor
+*/
+Parser(): default_stack_size(100)
+{
+ pstop_calculating = 0;
+ puser_variables = 0;
+ puser_functions = 0;
+ pfunction_local_variables = 0;
+ base = 10;
+ deg_rad_grad = 1;
+ error = err_ok;
+ group = 0;
+ comma = '.';
+ comma2 = ',';
+ param_sep = 0;
+
+ CreateFunctionsTable();
+ CreateVariablesTable();
+ CreateMathematicalOperatorsTable();
+}
+
+
+/*!
+ the assignment operator
+*/
+Parser<ValueType> & operator=(const Parser<ValueType> & p)
+{
+ pstop_calculating = p.pstop_calculating;
+ puser_variables = p.puser_variables;
+ puser_functions = p.puser_functions;
+ pfunction_local_variables = 0;
+ base = p.base;
+ deg_rad_grad = p.deg_rad_grad;
+ error = p.error;
+ group = p.group;
+ comma = p.comma;
+ comma2 = p.comma2;
+ param_sep = p.param_sep;
+
+ /*
+ we don't have to call 'CreateFunctionsTable()' etc.
+ we can only copy these tables
+ */
+ functions_table = p.functions_table;
+ variables_table = p.variables_table;
+ operators_table = p.operators_table;
+
+ visited_variables = p.visited_variables;
+ visited_functions = p.visited_functions;
+
+return *this;
+}
+
+
+/*!
+ the copying constructor
+*/
+Parser(const Parser<ValueType> & p): default_stack_size(p.default_stack_size)
+{
+ operator=(p);
+}
+
+
+/*!
+ the new base of mathematic system
+ default is 10
+*/
+void SetBase(int b)
+{
+ if( b>=2 && b<=16 )
+ base = b;
+}
+
+
+/*!
+ the unit of angles used in: sin,cos,tan,cot,asin,acos,atan,acot
+ 0 - deg
+ 1 - rad (default)
+ 2 - grad
+*/
+void SetDegRadGrad(int angle)
+{
+ if( angle >= 0 || angle <= 2 )
+ deg_rad_grad = angle;
+}
+
+/*!
+ this method sets a pointer to the object which tell us whether we should stop
+ calculations
+*/
+void SetStopObject(const volatile StopCalculating * ps)
+{
+ pstop_calculating = ps;
+}
+
+
+/*!
+ this method sets the new table of user-defined variables
+ if you don't want any other variables just put zero value into the 'puser_variables' variable
+
+ (you can have only one table at the same time)
+*/
+void SetVariables(const Objects * pv)
+{
+ puser_variables = pv;
+}
+
+
+/*!
+ this method sets the new table of user-defined functions
+ if you don't want any other functions just put zero value into the 'puser_functions' variable
+
+ (you can have only one table at the same time)
+*/
+void SetFunctions(const Objects * pf)
+{
+ puser_functions = pf;
+}
+
+
+/*!
+ setting the group character
+ default zero (not used)
+*/
+void SetGroup(int g)
+{
+ group = g;
+}
+
+
+/*!
+ setting the main comma operator and the additional comma operator
+ the additional operator can be zero (which means it is not used)
+ default are: '.' and ','
+*/
+void SetComma(int c, int c2 = 0)
+{
+ comma = c;
+ comma2 = c2;
+}
+
+
+/*!
+ setting an additional character which is used as a parameters separator
+ the main parameters separator is a semicolon (is used always)
+
+ this character is used also as a global separator
+*/
+void SetParamSep(int s)
+{
+ param_sep = s;
+}
+
+
+/*!
+ the main method using for parsing string
+*/
+ErrorCode Parse(const char * str)
+{
+ stack_index = 0;
+ pstring = str;
+ error = err_ok;
+ calculated = false;
+
+ stack.resize( default_stack_size );
+
+ try
+ {
+ Parse();
+ }
+ catch(ErrorCode c)
+ {
+ error = c;
+ calculated = false;
+ }
+
+ NormalizeStack();
+
+return error;
+}
+
+
+/*!
+ the main method using for parsing string
+*/
+ErrorCode Parse(const std::string & str)
+{
+ return Parse(str.c_str());
+}
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+/*!
+ the main method using for parsing string
+*/
+ErrorCode Parse(const wchar_t * str)
+{
+ Misc::AssignString(wide_to_ansi, str);
+
+return Parse(wide_to_ansi.c_str());
+
+ // !! wide_to_ansi clearing can be added here
+}
+
+
+/*!
+ the main method using for parsing string
+*/
+ErrorCode Parse(const std::wstring & str)
+{
+ return Parse(str.c_str());
+}
+
+#endif
+
+
+/*!
+ this method returns true is something was calculated
+ (at least one mathematical operator was used or a function or variable)
+ e.g. true if the string to Parse() looked like this:
+ "1+1"
+ "2*3"
+ "sin(5)"
+
+ if the string was e.g. "678" the result is false
+*/
+bool Calculated()
+{
+ return calculated;
+}
+
+
+/*!
+ initializing coefficients used when calculating the gamma (or factorial) function
+ this speed up the next calculations
+ you don't have to call this method explicitly
+ these coefficients will be calculated when needed
+*/
+void InitCGamma()
+{
+ cgamma.InitAll();
+}
+
+
+};
+
+
+
+} // namespace
+
+
+#endif
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h b/src/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h
new file mode 100644
index 0000000..586227f
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h
@@ -0,0 +1,250 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmaththreads
+#define headerfilettmaththreads
+
+#include "ttmathtypes.h"
+
+#ifdef TTMATH_WIN32_THREADS
+#include <windows.h>
+#include <cstdio>
+#endif
+
+#ifdef TTMATH_POSIX_THREADS
+#include <pthread.h>
+#endif
+
+
+
+/*!
+ \file ttmaththreads.h
+ \brief Some objects used in multithreads environment
+*/
+
+
+/*
+ this is a simple skeleton of a program in multithreads environment:
+
+ #define TTMATH_MULTITHREADS
+ #include<ttmath/ttmath.h>
+
+ TTMATH_MULTITHREADS_HELPER
+
+ int main()
+ {
+ [...]
+ }
+
+ make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
+ use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
+*/
+
+
+namespace ttmath
+{
+
+
+#ifdef TTMATH_WIN32_THREADS
+
+ /*
+ we use win32 threads
+ */
+
+
+ /*!
+ in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
+ somewhere in *.cpp file
+
+ (at the moment in win32 this macro does nothing)
+ */
+ #define TTMATH_MULTITHREADS_HELPER
+
+
+ /*!
+ objects of this class are used to synchronize
+ */
+ class ThreadLock
+ {
+ HANDLE mutex_handle;
+
+
+ void CreateName(char * buffer) const
+ {
+ #ifdef _MSC_VER
+ #pragma warning (disable : 4996)
+ // warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
+ #endif
+
+ sprintf(buffer, "TTMATH_LOCK_%ul", (unsigned long)GetCurrentProcessId());
+
+ #ifdef _MSC_VER
+ #pragma warning (default : 4996)
+ #endif
+ }
+
+
+ public:
+
+ bool Lock()
+ {
+ char buffer[50];
+
+ CreateName(buffer);
+ mutex_handle = CreateMutexA(0, false, buffer);
+
+ if( mutex_handle == 0 )
+ return false;
+
+ WaitForSingleObject(mutex_handle, INFINITE);
+
+ return true;
+ }
+
+
+ ThreadLock()
+ {
+ mutex_handle = 0;
+ }
+
+
+ ~ThreadLock()
+ {
+ if( mutex_handle != 0 )
+ {
+ ReleaseMutex(mutex_handle);
+ CloseHandle(mutex_handle);
+ }
+ }
+ };
+
+#endif // #ifdef TTMATH_WIN32_THREADS
+
+
+
+
+
+#ifdef TTMATH_POSIX_THREADS
+
+ /*
+ we use posix threads
+ */
+
+
+ /*!
+ in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
+ somewhere in *.cpp file
+ (this macro defines a pthread_mutex_t object used by TTMath library)
+ */
+ #define TTMATH_MULTITHREADS_HELPER \
+ namespace ttmath \
+ { \
+ pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER; \
+ }
+
+
+ /*!
+ ttmath_mutex will be defined by TTMATH_MULTITHREADS_HELPER macro
+ */
+ extern pthread_mutex_t ttmath_mutex;
+
+
+ /*!
+ objects of this class are used to synchronize
+ */
+ class ThreadLock
+ {
+ public:
+
+ bool Lock()
+ {
+ if( pthread_mutex_lock(&ttmath_mutex) != 0 )
+ return false;
+
+ return true;
+ }
+
+
+ ~ThreadLock()
+ {
+ pthread_mutex_unlock(&ttmath_mutex);
+ }
+ };
+
+#endif // #ifdef TTMATH_POSIX_THREADS
+
+
+
+
+#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
+
+ /*!
+ we don't use win32 and pthreads
+ */
+
+ /*!
+ */
+ #define TTMATH_MULTITHREADS_HELPER
+
+
+ /*!
+ objects of this class are used to synchronize
+ actually we don't synchronize, the method Lock() returns always 'false'
+ */
+ class ThreadLock
+ {
+ public:
+
+ bool Lock()
+ {
+ return false;
+ }
+ };
+
+
+#endif // #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
+
+
+
+
+
+} // namespace
+
+#endif
+
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h
new file mode 100644
index 0000000..539c100
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h
@@ -0,0 +1,675 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2011, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef headerfilettmathtypes
+#define headerfilettmathtypes
+
+/*!
+ \file ttmathtypes.h
+ \brief constants used in the library
+
+ As our library is written in header files (templates) we cannot use
+ constants like 'const int' etc. because we should have some source files
+ *.cpp to define this variables. Only what we can have are constants
+ defined by #define preprocessor macros.
+
+ All macros are preceded by TTMATH_ prefix
+*/
+
+
+#include <stdexcept>
+#include <sstream>
+#include <vector>
+
+#ifndef _MSC_VER
+#include <stdint.h>
+// for uint64_t and int64_t on a 32 bit platform
+#endif
+
+
+
+/*!
+ the version of the library
+
+ TTMATH_PRERELEASE_VER is either zero or one
+ zero means that this is the release version of the library
+ (one means something like beta)
+*/
+#define TTMATH_MAJOR_VER 0
+#define TTMATH_MINOR_VER 9
+#define TTMATH_REVISION_VER 3
+
+#define TTMATH_PRERELEASE_VER 1
+
+
+
+/*!
+ you can define a platform explicitly by defining either
+ TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
+*/
+#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
+
+ #if !defined _M_X64 && !defined __x86_64__
+
+ /*
+ other platforms than x86 and amd64 are not recognized at the moment
+ so you should set TTMATH_PLATFORMxx manually
+ */
+
+ // we're using a 32bit platform
+ #define TTMATH_PLATFORM32
+
+ #else
+
+ // we're using a 64bit platform
+ #define TTMATH_PLATFORM64
+
+ #endif
+
+#endif
+
+
+/*!
+ asm version of the library is available by default only for:
+ x86 and amd64 platforms and for Microsoft Visual and GCC compilers
+
+ but you can force using asm version (the same asm as for Microsoft Visual)
+ by defining TTMATH_FORCEASM macro
+ you have to be sure that your compiler accept such an asm format
+*/
+#ifndef TTMATH_FORCEASM
+
+ #if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
+ /*!
+ x86 architecture:
+ __i386__ defined by GNU C
+ _X86_ defined by MinGW32
+ _M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
+
+ amd64 architecture:
+ __x86_64__ defined by GNU C and Sun Studio
+ _M_X64 defined by Visual Studio
+
+ asm version is available only for x86 or amd64 platforms
+ */
+ #define TTMATH_NOASM
+ #endif
+
+
+
+ #if !defined _MSC_VER && !defined __GNUC__
+ /*!
+ another compilers than MS VC or GCC by default use no asm version
+ */
+ #define TTMATH_NOASM
+ #endif
+
+#endif
+
+
+namespace ttmath
+{
+
+
+#ifdef TTMATH_PLATFORM32
+
+ /*!
+ on 32bit platforms one word (uint, sint) will be equal 32bits
+ */
+ typedef unsigned int uint;
+ typedef signed int sint;
+
+ /*!
+ on 32 bit platform ulint and slint will be equal 64 bits
+ */
+ #ifdef _MSC_VER
+ // long long on MS Windows (Visual and GCC mingw compilers) have 64 bits
+ // stdint.h is not available on Visual Studio prior to VS 2010 version
+ typedef unsigned long long int ulint;
+ typedef signed long long int slint;
+ #else
+ // we do not use 'long' here because there is a difference in unix and windows
+ // environments: in unix 'long' has 64 bits but in windows it has only 32 bits
+ typedef uint64_t ulint;
+ typedef int64_t slint;
+ #endif
+
+ /*!
+ how many bits there are in the uint type
+ */
+ #define TTMATH_BITS_PER_UINT 32u
+
+ /*!
+ the mask for the highest bit in the unsigned 32bit word (2^31)
+ */
+ #define TTMATH_UINT_HIGHEST_BIT 2147483648u
+
+ /*!
+ the max value of the unsigned 32bit word (2^32 - 1)
+ (all bits equal one)
+ */
+ #define TTMATH_UINT_MAX_VALUE 4294967295u
+
+ /*!
+ the number of words (32bit words on 32bit platform)
+ which are kept in built-in variables for a Big<> type
+ (these variables are defined in ttmathbig.h)
+ */
+ #define TTMATH_BUILTIN_VARIABLES_SIZE 256u
+
+ /*!
+ this macro returns the number of machine words
+ capable to hold min_bits bits
+ e.g. TTMATH_BITS(128) returns 4
+ */
+ #define TTMATH_BITS(min_bits) ((min_bits-1)/32 + 1)
+
+#else
+
+ /*!
+ on 64bit platforms one word (uint, sint) will be equal 64bits
+ */
+ #ifdef _MSC_VER
+ /* in VC 'long' type has 32 bits, __int64 is VC extension */
+ typedef unsigned __int64 uint;
+ typedef signed __int64 sint;
+ #else
+ typedef unsigned long uint;
+ typedef signed long sint;
+ #endif
+
+ /*!
+ on 64bit platforms we do not define ulint and slint
+ */
+
+ /*!
+ how many bits there are in the uint type
+ */
+ #define TTMATH_BITS_PER_UINT 64ul
+
+ /*!
+ the mask for the highest bit in the unsigned 64bit word (2^63)
+ */
+ #define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
+
+ /*!
+ the max value of the unsigned 64bit word (2^64 - 1)
+ (all bits equal one)
+ */
+ #define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
+
+ /*!
+ the number of words (64bit words on 64bit platforms)
+ which are kept in built-in variables for a Big<> type
+ (these variables are defined in ttmathbig.h)
+ */
+ #define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
+
+ /*!
+ this macro returns the number of machine words
+ capable to hold min_bits bits
+ e.g. TTMATH_BITS(128) returns 2
+ */
+ #define TTMATH_BITS(min_bits) ((min_bits-1)/64 + 1)
+
+#endif
+}
+
+
+#if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
+ #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
+
+ #if defined(_WIN32)
+ #define TTMATH_WIN32_THREADS
+ #elif defined(unix) || defined(__unix__) || defined(__unix)
+ #define TTMATH_POSIX_THREADS
+ #endif
+
+ #endif
+#endif
+
+
+
+/*!
+ this variable defines how many iterations are performed
+ during some kind of calculating when we're making any long formulas
+ (for example Taylor series)
+
+ it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
+
+ note! there'll not be so many iterations, iterations are stopped when
+ there is no sense to continue calculating (for example when the result
+ still remains unchanged after adding next series and we know that the next
+ series are smaller than previous ones)
+*/
+#define TTMATH_ARITHMETIC_MAX_LOOP 10000
+
+
+
+/*!
+ this is a limit when calculating Karatsuba multiplication
+ if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
+ the Karatsuba algorithm will use standard schoolbook multiplication
+*/
+#ifdef TTMATH_DEBUG_LOG
+ // if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
+ #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
+#else
+ #ifdef __GNUC__
+ #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
+ #else
+ #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
+ #endif
+#endif
+
+
+/*!
+ this is a special value used when calculating the Gamma(x) function
+ if x is greater than this value then the Gamma(x) will be calculated using
+ some kind of series
+
+ don't use smaller values than about 100
+*/
+#define TTMATH_GAMMA_BOUNDARY 2000
+
+
+
+
+
+namespace ttmath
+{
+
+ /*!
+ lib type codes:
+ asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
+ asm_gcc_32 - with asm code designed for GCC (32 bits)
+ asm_vc_64 - with asm for VC (64 bit)
+ asm_gcc_64 - with asm for GCC (64 bit)
+ no_asm_32 - pure C++ version (32 bit) - without any asm code
+ no_asm_64 - pure C++ version (64 bit) - without any asm code
+ */
+ enum LibTypeCode
+ {
+ asm_vc_32 = 0,
+ asm_gcc_32,
+ asm_vc_64,
+ asm_gcc_64,
+ no_asm_32,
+ no_asm_64
+ };
+
+
+ /*!
+ error codes
+ */
+ enum ErrorCode
+ {
+ err_ok = 0,
+ err_nothing_has_read,
+ err_unknown_character,
+ err_unexpected_final_bracket,
+ err_stack_not_clear,
+ err_unknown_variable,
+ err_division_by_zero,
+ err_interrupt,
+ err_overflow,
+ err_unknown_function,
+ err_unknown_operator,
+ err_unexpected_semicolon_operator,
+ err_improper_amount_of_arguments,
+ err_improper_argument,
+ err_unexpected_end,
+ err_internal_error,
+ err_incorrect_name,
+ err_incorrect_value,
+ err_variable_exists,
+ err_variable_loop,
+ err_functions_loop,
+ err_must_be_only_one_value,
+ err_object_exists,
+ err_unknown_object,
+ err_still_calculating,
+ err_in_short_form_used_function,
+ err_percent_from
+ };
+
+
+ /*!
+ this struct is used when converting to/from a string
+ /temporarily only in Big::ToString() and Big::FromString()/
+ */
+ struct Conv
+ {
+ /*!
+ base (radix) on which the value will be shown (or read)
+ default: 10
+ */
+ uint base;
+
+
+ /*!
+ used only in Big::ToString()
+ if true the value will be always shown in the scientific mode, e.g: 123e+30
+ default: false
+ */
+ bool scient;
+
+
+ /*!
+ used only in Big::ToString()
+ if scient is false then the value will be printed in the scientific mode
+ only if the exponent is greater than scien_from
+ default: 15
+ */
+ sint scient_from;
+
+
+ /*!
+ if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
+ and the result value is not an integer then we make an additional rounding
+ (after converting the last digit from the result is skipped)
+ default: true
+
+ e.g.
+ Conv c;
+ c.base_round = false;
+ Big<1, 1> a = "0.1"; // decimal input
+ std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
+ */
+ bool base_round;
+
+
+ /*!
+ used only in Big::ToString()
+ tells how many digits after comma are possible
+ default: -1 which means all digits are printed
+
+ set it to zero if you want integer value only
+
+ for example when the value is:
+ 12.345678 and 'round' is 4
+ then the result will be
+ 12.3457 (the last digit was rounded)
+ */
+ sint round;
+
+
+ /*!
+ if true that not mattered digits in the mantissa will be cut off
+ (zero characters at the end -- after the comma operator)
+ e.g. 1234,78000 will be: 1234,78
+ default: true
+ */
+ bool trim_zeroes;
+
+
+ /*!
+ the main comma operator (used when reading and writing)
+ default is a dot '.'
+ */
+ uint comma;
+
+
+ /*!
+ additional comma operator (used only when reading)
+ if you don't want it just set it to zero
+ default is a comma ','
+
+ this allowes you to convert from a value:
+ 123.45 as well as from 123,45
+ */
+ uint comma2;
+
+
+ /*!
+ it sets the character which is used for grouping
+ if group=' ' then: 1234,56789 will be printed as: 1 234,567 89
+
+ if you don't want grouping just set it to zero (which is default)
+ */
+ uint group;
+
+
+ /*!
+ how many digits should be grouped (it is used if 'group' is non zero)
+ default: 3
+ */
+ uint group_digits;
+
+
+ /*!
+ */
+ uint group_exp; // not implemented yet
+
+
+
+
+ Conv()
+ {
+ // default values
+ base = 10;
+ scient = false;
+ scient_from = 15;
+ base_round = true;
+ round = -1;
+ trim_zeroes = true;
+ comma = '.';
+ comma2 = ',';
+ group = 0;
+ group_digits = 3;
+ group_exp = 0;
+ }
+ };
+
+
+
+ /*!
+ this simple class can be used in multithreading model
+ (you can write your own class derived from this one)
+
+ for example: in some functions like Factorial()
+ /at the moment only Factorial/ you can give a pointer to
+ the 'stop object', if the method WasStopSignal() of this
+ object returns true that means we should break the calculating
+ and return
+ */
+ class StopCalculating
+ {
+ public:
+ virtual bool WasStopSignal() const volatile { return false; }
+ virtual ~StopCalculating(){}
+ };
+
+
+ /*!
+ a small class which is useful when compiling with gcc
+
+ object of this type holds the name and the line of a file
+ in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used
+ */
+ class ExceptionInfo
+ {
+ const char * file;
+ int line;
+
+ public:
+ ExceptionInfo() : file(0), line(0) {}
+ ExceptionInfo(const char * f, int l) : file(f), line(l) {}
+
+ std::string Where() const
+ {
+ if( !file )
+ return "unknown";
+
+ std::ostringstream result;
+ result << file << ":" << line;
+
+ return result.str();
+ }
+ };
+
+
+ /*!
+ A small class used for reporting 'reference' errors
+
+ In the library is used macro TTMATH_REFERENCE_ASSERT which
+ can throw an exception of this type
+
+ ** from version 0.9.2 this macro is removed from all methods
+ in public interface so you don't have to worry about it **
+
+ If you compile with gcc you can get a small benefit
+ from using method Where() (it returns std::string) with
+ the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
+ was used)
+ */
+ class ReferenceError : public std::logic_error, public ExceptionInfo
+ {
+ public:
+
+ ReferenceError() : std::logic_error("reference error")
+ {
+ }
+
+ ReferenceError(const char * f, int l) :
+ std::logic_error("reference error"), ExceptionInfo(f,l)
+ {
+ }
+
+ std::string Where() const
+ {
+ return ExceptionInfo::Where();
+ }
+ };
+
+
+ /*!
+ a small class used for reporting errors
+
+ in the library is used macro TTMATH_ASSERT which
+ (if the condition in it is false) throw an exception
+ of this type
+
+ if you compile with gcc you can get a small benefit
+ from using method Where() (it returns std::string) with
+ the name and the line of a file where the macro TTMATH_ASSERT
+ was used)
+ */
+ class RuntimeError : public std::runtime_error, public ExceptionInfo
+ {
+ public:
+
+ RuntimeError() : std::runtime_error("internal error")
+ {
+ }
+
+ RuntimeError(const char * f, int l) :
+ std::runtime_error("internal error"), ExceptionInfo(f,l)
+ {
+ }
+
+ std::string Where() const
+ {
+ return ExceptionInfo::Where();
+ }
+ };
+
+
+
+ /*!
+ TTMATH_DEBUG
+ this macro enables further testing during writing your code
+ you don't have to define it in a release mode
+
+ if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
+ are set as well and these macros can throw an exception if a condition in it
+ is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
+
+ TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
+ */
+ #if defined DEBUG || defined _DEBUG
+ #define TTMATH_DEBUG
+ #endif
+
+
+ #ifdef TTMATH_DEBUG
+
+ #if defined(__FILE__) && defined(__LINE__)
+
+ #define TTMATH_REFERENCE_ASSERT(expression) \
+ if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
+
+ #define TTMATH_ASSERT(expression) \
+ if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
+
+ #else
+
+ #define TTMATH_REFERENCE_ASSERT(expression) \
+ if( &(expression) == this ) throw ReferenceError();
+
+ #define TTMATH_ASSERT(expression) \
+ if( !(expression) ) throw RuntimeError();
+ #endif
+
+ #else
+ #define TTMATH_REFERENCE_ASSERT(expression)
+ #define TTMATH_ASSERT(expression)
+ #endif
+
+
+
+ #ifdef TTMATH_DEBUG_LOG
+ #define TTMATH_LOG(msg) PrintLog(msg, std::cout);
+ #define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
+ #define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
+ #define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
+ #else
+ #define TTMATH_LOG(msg)
+ #define TTMATH_LOGC(msg, carry)
+ #define TTMATH_VECTOR_LOG(msg, vector, len)
+ #define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
+ #endif
+
+
+
+
+} // namespace
+
+
+#endif
+
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathuint.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint.h
new file mode 100644
index 0000000..d0f6df1
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint.h
@@ -0,0 +1,4121 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2011, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathuint
+#define headerfilettmathuint
+
+
+/*!
+ \file ttmathuint.h
+ \brief template class UInt<uint>
+*/
+
+#include <iostream>
+#include <iomanip>
+
+
+#include "ttmathtypes.h"
+#include "ttmathmisc.h"
+
+
+
+/*!
+ \brief a namespace for the TTMath library
+*/
+namespace ttmath
+{
+
+/*!
+ \brief UInt implements a big integer value without a sign
+
+ value_size - how many bytes specify our value
+ on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
+ on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
+ value_size = 1,2,3,4,5,6....
+*/
+template<uint value_size>
+class UInt
+{
+public:
+
+ /*!
+ buffer for the integer value
+ table[0] - the lowest word of the value
+ */
+ uint table[value_size];
+
+
+
+ /*!
+ some methods used for debugging purposes
+ */
+
+
+ /*!
+ this method is only for debugging purposes or when we want to make
+ a table of a variable (constant) in ttmathbig.h
+
+ it prints the table in a nice form of several columns
+ */
+ template<class ostream_type>
+ void PrintTable(ostream_type & output) const
+ {
+ // how many columns there'll be
+ const int columns = 8;
+
+ int c = 1;
+ for(int i=value_size-1 ; i>=0 ; --i)
+ {
+ output << "0x" << std::setfill('0');
+
+ #ifdef TTMATH_PLATFORM32
+ output << std::setw(8);
+ #else
+ output << std::setw(16);
+ #endif
+
+ output << std::hex << table[i];
+
+ if( i>0 )
+ {
+ output << ", ";
+
+ if( ++c > columns )
+ {
+ output << std::endl;
+ c = 1;
+ }
+ }
+ }
+
+ output << std::dec << std::endl;
+ }
+
+
+ /*!
+ this method is used when macro TTMATH_DEBUG_LOG is defined
+ */
+ template<class char_type, class ostream_type>
+ static void PrintVectorLog(const char_type * msg, ostream_type & output, const uint * vector, uint vector_len)
+ {
+ output << msg << std::endl;
+
+ for(uint i=0 ; i<vector_len ; ++i)
+ output << " table[" << i << "]: " << vector[i] << std::endl;
+ }
+
+
+ /*!
+ this method is used when macro TTMATH_DEBUG_LOG is defined
+ */
+ template<class char_type, class ostream_type>
+ static void PrintVectorLog(const char_type * msg, uint carry, ostream_type & output, const uint * vector, uint vector_len)
+ {
+ PrintVectorLog(msg, output, vector, vector_len);
+ output << " carry: " << carry << std::endl;
+ }
+
+
+ /*!
+ this method is used when macro TTMATH_DEBUG_LOG is defined
+ */
+ template<class char_type, class ostream_type>
+ void PrintLog(const char_type * msg, ostream_type & output) const
+ {
+ PrintVectorLog(msg, output, table, value_size);
+ }
+
+
+ /*!
+ this method is used when macro TTMATH_DEBUG_LOG is defined
+ */
+ template<class char_type, class ostream_type>
+ void PrintLog(const char_type * msg, uint carry, ostream_type & output) const
+ {
+ PrintVectorLog(msg, output, table, value_size);
+ output << " carry: " << carry << std::endl;
+ }
+
+
+ /*!
+ this method returns the size of the table
+ */
+ uint Size() const
+ {
+ return value_size;
+ }
+
+
+ /*!
+ this method sets zero
+ */
+ void SetZero()
+ {
+ // in the future here can be 'memset'
+
+ for(uint i=0 ; i<value_size ; ++i)
+ table[i] = 0;
+
+ TTMATH_LOG("UInt::SetZero")
+ }
+
+
+ /*!
+ this method sets one
+ */
+ void SetOne()
+ {
+ SetZero();
+ table[0] = 1;
+
+ TTMATH_LOG("UInt::SetOne")
+ }
+
+
+ /*!
+ this method sets the max value which this class can hold
+ (all bits will be one)
+ */
+ void SetMax()
+ {
+ for(uint i=0 ; i<value_size ; ++i)
+ table[i] = TTMATH_UINT_MAX_VALUE;
+
+ TTMATH_LOG("UInt::SetMax")
+ }
+
+
+ /*!
+ this method sets the min value which this class can hold
+ (for an unsigned integer value the zero is the smallest value)
+ */
+ void SetMin()
+ {
+ SetZero();
+
+ TTMATH_LOG("UInt::SetMin")
+ }
+
+
+ /*!
+ this method swappes this for an argument
+ */
+ void Swap(UInt<value_size> & ss2)
+ {
+ for(uint i=0 ; i<value_size ; ++i)
+ {
+ uint temp = table[i];
+ table[i] = ss2.table[i];
+ ss2.table[i] = temp;
+ }
+ }
+
+
+#ifdef TTMATH_PLATFORM32
+
+ /*!
+ this method copies the value stored in an another table
+ (warning: first values in temp_table are the highest words -- it's different
+ from our table)
+
+ we copy as many words as it is possible
+
+ if temp_table_len is bigger than value_size we'll try to round
+ the lowest word from table depending on the last not used bit in temp_table
+ (this rounding isn't a perfect rounding -- look at the description below)
+
+ and if temp_table_len is smaller than value_size we'll clear the rest words
+ in the table
+ */
+ void SetFromTable(const uint * temp_table, uint temp_table_len)
+ {
+ uint temp_table_index = 0;
+ sint i; // 'i' with a sign
+
+ for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
+ table[i] = temp_table[ temp_table_index ];
+
+
+ // rounding mantissa
+ if( temp_table_index < temp_table_len )
+ {
+ if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+ {
+ /*
+ very simply rounding
+ if the bit from not used last word from temp_table is set to one
+ we're rouding the lowest word in the table
+
+ in fact there should be a normal addition but
+ we don't use Add() or AddTwoInts() because these methods
+ can set a carry and then there'll be a small problem
+ for optimization
+ */
+ if( table[0] != TTMATH_UINT_MAX_VALUE )
+ ++table[0];
+ }
+ }
+
+ // cleaning the rest of the mantissa
+ for( ; i>=0 ; --i)
+ table[i] = 0;
+
+
+ TTMATH_LOG("UInt::SetFromTable")
+ }
+
+#endif
+
+
+#ifdef TTMATH_PLATFORM64
+ /*!
+ this method copies the value stored in an another table
+ (warning: first values in temp_table are the highest words -- it's different
+ from our table)
+
+ ***this method is created only on a 64bit platform***
+
+ we copy as many words as it is possible
+
+ if temp_table_len is bigger than value_size we'll try to round
+ the lowest word from table depending on the last not used bit in temp_table
+ (this rounding isn't a perfect rounding -- look at the description below)
+
+ and if temp_table_len is smaller than value_size we'll clear the rest words
+ in the table
+
+ warning: we're using 'temp_table' as a pointer at 32bit words
+ */
+ void SetFromTable(const unsigned int * temp_table, uint temp_table_len)
+ {
+ uint temp_table_index = 0;
+ sint i; // 'i' with a sign
+
+ for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
+ {
+ table[i] = uint(temp_table[ temp_table_index ]) << 32;
+
+ ++temp_table_index;
+
+ if( temp_table_index<temp_table_len )
+ table[i] |= temp_table[ temp_table_index ];
+ }
+
+
+ // rounding mantissa
+ if( temp_table_index < temp_table_len )
+ {
+ if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+ {
+ /*
+ very simply rounding
+ if the bit from not used last word from temp_table is set to one
+ we're rouding the lowest word in the table
+
+ in fact there should be a normal addition but
+ we don't use Add() or AddTwoInts() because these methods
+ can set a carry and then there'll be a small problem
+ for optimization
+ */
+ if( table[0] != TTMATH_UINT_MAX_VALUE )
+ ++table[0];
+ }
+ }
+
+ // cleaning the rest of the mantissa
+ for( ; i >= 0 ; --i)
+ table[i] = 0;
+
+ TTMATH_LOG("UInt::SetFromTable")
+ }
+
+#endif
+
+
+
+
+
+ /*!
+ *
+ * basic mathematic functions
+ *
+ */
+
+
+
+
+ /*!
+ this method adds one to the existing value
+ */
+ uint AddOne()
+ {
+ return AddInt(1);
+ }
+
+
+ /*!
+ this method subtracts one from the existing value
+ */
+ uint SubOne()
+ {
+ return SubInt(1);
+ }
+
+
+private:
+
+
+ /*!
+ an auxiliary method for moving bits into the left hand side
+
+ this method moves only words
+ */
+ void RclMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c)
+ {
+ rest_bits = bits % TTMATH_BITS_PER_UINT;
+ uint all_words = bits / TTMATH_BITS_PER_UINT;
+ uint mask = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
+
+
+ if( all_words >= value_size )
+ {
+ if( all_words == value_size && rest_bits == 0 )
+ last_c = table[0] & 1;
+ // else: last_c is default set to 0
+
+ // clearing
+ for(uint i = 0 ; i<value_size ; ++i)
+ table[i] = mask;
+
+ rest_bits = 0;
+ }
+ else
+ if( all_words > 0 )
+ {
+ // 0 < all_words < value_size
+
+ sint first, second;
+ last_c = table[value_size - all_words] & 1; // all_words is greater than 0
+
+ // copying the first part of the value
+ for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second)
+ table[first] = table[second];
+
+ // setting the rest to 'c'
+ for( ; first>=0 ; --first )
+ table[first] = mask;
+ }
+
+ TTMATH_LOG("UInt::RclMoveAllWords")
+ }
+
+public:
+
+ /*!
+ moving all bits into the left side 'bits' times
+ return value <- this <- C
+
+ bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
+ or it can be even bigger then all bits will be set to 'c'
+
+ the value c will be set into the lowest bits
+ and the method returns state of the last moved bit
+ */
+ uint Rcl(uint bits, uint c=0)
+ {
+ uint last_c = 0;
+ uint rest_bits = bits;
+
+ if( bits == 0 )
+ return 0;
+
+ if( bits >= TTMATH_BITS_PER_UINT )
+ RclMoveAllWords(rest_bits, last_c, bits, c);
+
+ if( rest_bits == 0 )
+ {
+ TTMATH_LOG("UInt::Rcl")
+ return last_c;
+ }
+
+ // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
+ if( rest_bits == 1 )
+ {
+ last_c = Rcl2_one(c);
+ }
+ else if( rest_bits == 2 )
+ {
+ // performance tests showed that for rest_bits==2 it's better to use Rcl2_one twice instead of Rcl2(2,c)
+ Rcl2_one(c);
+ last_c = Rcl2_one(c);
+ }
+ else
+ {
+ last_c = Rcl2(rest_bits, c);
+ }
+
+ TTMATH_LOGC("UInt::Rcl", last_c)
+
+ return last_c;
+ }
+
+private:
+
+ /*!
+ an auxiliary method for moving bits into the right hand side
+
+ this method moves only words
+ */
+ void RcrMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c)
+ {
+ rest_bits = bits % TTMATH_BITS_PER_UINT;
+ uint all_words = bits / TTMATH_BITS_PER_UINT;
+ uint mask = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
+
+
+ if( all_words >= value_size )
+ {
+ if( all_words == value_size && rest_bits == 0 )
+ last_c = (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
+ // else: last_c is default set to 0
+
+ // clearing
+ for(uint i = 0 ; i<value_size ; ++i)
+ table[i] = mask;
+
+ rest_bits = 0;
+ }
+ else if( all_words > 0 )
+ {
+ // 0 < all_words < value_size
+
+ uint first, second;
+ last_c = (table[all_words - 1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; // all_words is > 0
+
+ // copying the first part of the value
+ for(first=0, second=all_words ; second<value_size ; ++first, ++second)
+ table[first] = table[second];
+
+ // setting the rest to 'c'
+ for( ; first<value_size ; ++first )
+ table[first] = mask;
+ }
+
+ TTMATH_LOG("UInt::RcrMoveAllWords")
+ }
+
+public:
+
+ /*!
+ moving all bits into the right side 'bits' times
+ c -> this -> return value
+
+ bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
+ or it can be even bigger then all bits will be set to 'c'
+
+ the value c will be set into the highest bits
+ and the method returns state of the last moved bit
+ */
+ uint Rcr(uint bits, uint c=0)
+ {
+ uint last_c = 0;
+ uint rest_bits = bits;
+
+ if( bits == 0 )
+ return 0;
+
+ if( bits >= TTMATH_BITS_PER_UINT )
+ RcrMoveAllWords(rest_bits, last_c, bits, c);
+
+ if( rest_bits == 0 )
+ {
+ TTMATH_LOG("UInt::Rcr")
+ return last_c;
+ }
+
+ // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
+ if( rest_bits == 1 )
+ {
+ last_c = Rcr2_one(c);
+ }
+ else if( rest_bits == 2 )
+ {
+ // performance tests showed that for rest_bits==2 it's better to use Rcr2_one twice instead of Rcr2(2,c)
+ Rcr2_one(c);
+ last_c = Rcr2_one(c);
+ }
+ else
+ {
+ last_c = Rcr2(rest_bits, c);
+ }
+
+ TTMATH_LOGC("UInt::Rcr", last_c)
+
+ return last_c;
+ }
+
+
+ /*!
+ this method moves all bits into the left side
+ (it returns value how many bits have been moved)
+ */
+ uint CompensationToLeft()
+ {
+ uint moving = 0;
+
+ // a - index a last word which is different from zero
+ sint a;
+ for(a=value_size-1 ; a>=0 && table[a]==0 ; --a);
+
+ if( a < 0 )
+ return moving; // all words in table have zero
+
+ if( a != value_size-1 )
+ {
+ moving += ( value_size-1 - a ) * TTMATH_BITS_PER_UINT;
+
+ // moving all words
+ sint i;
+ for(i=value_size-1 ; a>=0 ; --i, --a)
+ table[i] = table[a];
+
+ // setting the rest word to zero
+ for(; i>=0 ; --i)
+ table[i] = 0;
+ }
+
+ uint moving2 = FindLeadingBitInWord( table[value_size-1] );
+ // moving2 is different from -1 because the value table[value_size-1]
+ // is not zero
+
+ moving2 = TTMATH_BITS_PER_UINT - moving2 - 1;
+ Rcl(moving2);
+
+ TTMATH_LOG("UInt::CompensationToLeft")
+
+ return moving + moving2;
+ }
+
+
+ /*!
+ this method looks for the highest set bit
+
+ result:
+ if 'this' is not zero:
+ return value - true
+ 'table_id' - the index of a word <0..value_size-1>
+ 'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
+
+ if 'this' is zero:
+ return value - false
+ both 'table_id' and 'index' are zero
+ */
+ bool FindLeadingBit(uint & table_id, uint & index) const
+ {
+ for(table_id=value_size-1 ; table_id!=0 && table[table_id]==0 ; --table_id);
+
+ if( table_id==0 && table[table_id]==0 )
+ {
+ // is zero
+ index = 0;
+
+ return false;
+ }
+
+ // table[table_id] is different from 0
+ index = FindLeadingBitInWord( table[table_id] );
+
+ return true;
+ }
+
+
+ /*!
+ this method looks for the smallest set bit
+
+ result:
+ if 'this' is not zero:
+ return value - true
+ 'table_id' - the index of a word <0..value_size-1>
+ 'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
+
+ if 'this' is zero:
+ return value - false
+ both 'table_id' and 'index' are zero
+ */
+ bool FindLowestBit(uint & table_id, uint & index) const
+ {
+ for(table_id=0 ; table_id<value_size && table[table_id]==0 ; ++table_id);
+
+ if( table_id >= value_size )
+ {
+ // is zero
+ index = 0;
+ table_id = 0;
+
+ return false;
+ }
+
+ // table[table_id] is different from 0
+ index = FindLowestBitInWord( table[table_id] );
+
+ return true;
+ }
+
+
+ /*!
+ getting the 'bit_index' bit
+
+ bit_index bigger or equal zero
+ */
+ uint GetBit(uint bit_index) const
+ {
+ TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
+
+ uint index = bit_index / TTMATH_BITS_PER_UINT;
+ uint bit = bit_index % TTMATH_BITS_PER_UINT;
+
+ uint temp = table[index];
+ uint res = SetBitInWord(temp, bit);
+
+ return res;
+ }
+
+
+ /*!
+ setting the 'bit_index' bit
+ and returning the last state of the bit
+
+ bit_index bigger or equal zero
+ */
+ uint SetBit(uint bit_index)
+ {
+ TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
+
+ uint index = bit_index / TTMATH_BITS_PER_UINT;
+ uint bit = bit_index % TTMATH_BITS_PER_UINT;
+ uint res = SetBitInWord(table[index], bit);
+
+ TTMATH_LOG("UInt::SetBit")
+
+ return res;
+ }
+
+
+ /*!
+ this method performs a bitwise operation AND
+ */
+ void BitAnd(const UInt<value_size> & ss2)
+ {
+ for(uint x=0 ; x<value_size ; ++x)
+ table[x] &= ss2.table[x];
+
+ TTMATH_LOG("UInt::BitAnd")
+ }
+
+
+ /*!
+ this method performs a bitwise operation OR
+ */
+ void BitOr(const UInt<value_size> & ss2)
+ {
+ for(uint x=0 ; x<value_size ; ++x)
+ table[x] |= ss2.table[x];
+
+ TTMATH_LOG("UInt::BitOr")
+ }
+
+
+ /*!
+ this method performs a bitwise operation XOR
+ */
+ void BitXor(const UInt<value_size> & ss2)
+ {
+ for(uint x=0 ; x<value_size ; ++x)
+ table[x] ^= ss2.table[x];
+
+ TTMATH_LOG("UInt::BitXor")
+ }
+
+
+ /*!
+ this method performs a bitwise operation NOT
+ */
+ void BitNot()
+ {
+ for(uint x=0 ; x<value_size ; ++x)
+ table[x] = ~table[x];
+
+ TTMATH_LOG("UInt::BitNot")
+ }
+
+
+ /*!
+ this method performs a bitwise operation NOT but only
+ on the range of <0, leading_bit>
+
+ for example:
+ BitNot2(8) = BitNot2( 1000(bin) ) = 111(bin) = 7
+ */
+ void BitNot2()
+ {
+ uint table_id, index;
+
+ if( FindLeadingBit(table_id, index) )
+ {
+ for(uint x=0 ; x<table_id ; ++x)
+ table[x] = ~table[x];
+
+ uint mask = TTMATH_UINT_MAX_VALUE;
+ uint shift = TTMATH_BITS_PER_UINT - index - 1;
+
+ if(shift)
+ mask >>= shift;
+
+ table[table_id] ^= mask;
+ }
+ else
+ table[0] = 1;
+
+
+ TTMATH_LOG("UInt::BitNot2")
+ }
+
+
+
+ /*!
+ *
+ * Multiplication
+ *
+ *
+ */
+
+public:
+
+ /*!
+ multiplication: this = this * ss2
+
+ it can return a carry
+ */
+ uint MulInt(uint ss2)
+ {
+ uint r1, r2, x1;
+ uint c = 0;
+
+ UInt<value_size> u(*this);
+ SetZero();
+
+ if( ss2 == 0 )
+ {
+ TTMATH_LOGC("UInt::MulInt(uint)", 0)
+ return 0;
+ }
+
+ for(x1=0 ; x1<value_size-1 ; ++x1)
+ {
+ MulTwoWords(u.table[x1], ss2, &r2, &r1);
+ c += AddTwoInts(r2,r1,x1);
+ }
+
+ // x1 = value_size-1 (last word)
+ MulTwoWords(u.table[x1], ss2, &r2, &r1);
+ c += (r2!=0) ? 1 : 0;
+ c += AddInt(r1, x1);
+
+ TTMATH_LOGC("UInt::MulInt(uint)", c)
+
+ return (c==0)? 0 : 1;
+ }
+
+
+ /*!
+ multiplication: result = this * ss2
+
+ we're using this method only when result_size is greater than value_size
+ if so there will not be a carry
+ */
+ template<uint result_size>
+ void MulInt(uint ss2, UInt<result_size> & result) const
+ {
+ TTMATH_ASSERT( result_size > value_size )
+
+ uint r2,r1;
+ uint x1size=value_size;
+ uint x1start=0;
+
+ result.SetZero();
+
+ if( ss2 == 0 )
+ {
+ TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
+ return;
+ }
+
+ if( value_size > 2 )
+ {
+ // if the value_size is smaller than or equal to 2
+ // there is no sense to set x1size and x1start to another values
+
+ for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
+
+ if( x1size == 0 )
+ {
+ TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
+ return;
+ }
+
+ for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
+ }
+
+ for(uint x1=x1start ; x1<x1size ; ++x1)
+ {
+ MulTwoWords(table[x1], ss2, &r2, &r1 );
+ result.AddTwoInts(r2,r1,x1);
+ }
+
+ TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
+
+ return;
+ }
+
+
+
+ /*!
+ the multiplication 'this' = 'this' * ss2
+
+ algorithm: 100 - means automatically choose the fastest algorithm
+ */
+ uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
+ {
+ switch( algorithm )
+ {
+ case 1:
+ return Mul1(ss2);
+
+ case 2:
+ return Mul2(ss2);
+
+ case 3:
+ return Mul3(ss2);
+
+ case 100:
+ default:
+ return MulFastest(ss2);
+ }
+ }
+
+
+ /*!
+ the multiplication 'result' = 'this' * ss2
+
+ since the 'result' is twice bigger than 'this' and 'ss2'
+ this method never returns a carry
+
+ algorithm: 100 - means automatically choose the fastest algorithm
+ */
+ void MulBig(const UInt<value_size> & ss2,
+ UInt<value_size*2> & result,
+ uint algorithm = 100)
+ {
+ switch( algorithm )
+ {
+ case 1:
+ return Mul1Big(ss2, result);
+
+ case 2:
+ return Mul2Big(ss2, result);
+
+ case 3:
+ return Mul3Big(ss2, result);
+
+ case 100:
+ default:
+ return MulFastestBig(ss2, result);
+ }
+ }
+
+
+
+ /*!
+ the first version of the multiplication algorithm
+ */
+
+private:
+
+ /*!
+ multiplication: this = this * ss2
+
+ it returns carry if it has been
+ */
+ uint Mul1Ref(const UInt<value_size> & ss2)
+ {
+ TTMATH_REFERENCE_ASSERT( ss2 )
+
+ UInt<value_size> ss1( *this );
+ SetZero();
+
+ for(uint i=0; i < value_size*TTMATH_BITS_PER_UINT ; ++i)
+ {
+ if( Add(*this) )
+ {
+ TTMATH_LOGC("UInt::Mul1", 1)
+ return 1;
+ }
+
+ if( ss1.Rcl(1) )
+ if( Add(ss2) )
+ {
+ TTMATH_LOGC("UInt::Mul1", 1)
+ return 1;
+ }
+ }
+
+ TTMATH_LOGC("UInt::Mul1", 0)
+
+ return 0;
+ }
+
+
+public:
+
+ /*!
+ multiplication: this = this * ss2
+ can return carry
+ */
+ uint Mul1(const UInt<value_size> & ss2)
+ {
+ if( this == &ss2 )
+ {
+ UInt<value_size> copy_ss2(ss2);
+ return Mul1Ref(copy_ss2);
+ }
+ else
+ {
+ return Mul1Ref(ss2);
+ }
+ }
+
+
+ /*!
+ multiplication: result = this * ss2
+
+ result is twice bigger than 'this' and 'ss2'
+ this method never returns carry
+ */
+ void Mul1Big(const UInt<value_size> & ss2_, UInt<value_size*2> & result)
+ {
+ UInt<value_size*2> ss2;
+ uint i;
+
+ // copying *this into result and ss2_ into ss2
+ for(i=0 ; i<value_size ; ++i)
+ {
+ result.table[i] = table[i];
+ ss2.table[i] = ss2_.table[i];
+ }
+
+ // cleaning the highest bytes in result and ss2
+ for( ; i < value_size*2 ; ++i)
+ {
+ result.table[i] = 0;
+ ss2.table[i] = 0;
+ }
+
+ // multiply
+ // (there will not be a carry)
+ result.Mul1( ss2 );
+
+ TTMATH_LOG("UInt::Mul1Big")
+ }
+
+
+
+ /*!
+ the second version of the multiplication algorithm
+
+ this algorithm is similar to the 'schoolbook method' which is done by hand
+ */
+
+ /*!
+ multiplication: this = this * ss2
+
+ it returns carry if it has been
+ */
+ uint Mul2(const UInt<value_size> & ss2)
+ {
+ UInt<value_size*2> result;
+ uint i, c = 0;
+
+ Mul2Big(ss2, result);
+
+ // copying result
+ for(i=0 ; i<value_size ; ++i)
+ table[i] = result.table[i];
+
+ // testing carry
+ for( ; i<value_size*2 ; ++i)
+ if( result.table[i] != 0 )
+ {
+ c = 1;
+ break;
+ }
+
+ TTMATH_LOGC("UInt::Mul2", c)
+
+ return c;
+ }
+
+
+ /*!
+ multiplication: result = this * ss2
+
+ result is twice bigger than this and ss2
+ this method never returns carry
+ */
+ void Mul2Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
+ {
+ Mul2Big2<value_size>(table, ss2.table, result);
+
+ TTMATH_LOG("UInt::Mul2Big")
+ }
+
+
+private:
+
+ /*!
+ an auxiliary method for calculating the multiplication
+
+ arguments we're taking as pointers (this is to improve the Mul3Big2()- avoiding
+ unnecessary copying objects), the result should be taken as a pointer too,
+ but at the moment there is no method AddTwoInts() which can operate on pointers
+ */
+ template<uint ss_size>
+ void Mul2Big2(const uint * ss1, const uint * ss2, UInt<ss_size*2> & result)
+ {
+ uint x1size = ss_size, x2size = ss_size;
+ uint x1start = 0, x2start = 0;
+
+ if( ss_size > 2 )
+ {
+ // if the ss_size is smaller than or equal to 2
+ // there is no sense to set x1size (and others) to another values
+
+ for(x1size=ss_size ; x1size>0 && ss1[x1size-1]==0 ; --x1size);
+ for(x2size=ss_size ; x2size>0 && ss2[x2size-1]==0 ; --x2size);
+
+ for(x1start=0 ; x1start<x1size && ss1[x1start]==0 ; ++x1start);
+ for(x2start=0 ; x2start<x2size && ss2[x2start]==0 ; ++x2start);
+ }
+
+ Mul2Big3<ss_size>(ss1, ss2, result, x1start, x1size, x2start, x2size);
+ }
+
+
+
+ /*!
+ an auxiliary method for calculating the multiplication
+ */
+ template<uint ss_size>
+ void Mul2Big3(const uint * ss1, const uint * ss2, UInt<ss_size*2> & result, uint x1start, uint x1size, uint x2start, uint x2size)
+ {
+ uint r2, r1;
+
+ result.SetZero();
+
+ if( x1size==0 || x2size==0 )
+ return;
+
+ for(uint x1=x1start ; x1<x1size ; ++x1)
+ {
+ for(uint x2=x2start ; x2<x2size ; ++x2)
+ {
+ MulTwoWords(ss1[x1], ss2[x2], &r2, &r1);
+ result.AddTwoInts(r2, r1, x2+x1);
+ // here will never be a carry
+ }
+ }
+ }
+
+
+public:
+
+
+ /*!
+ multiplication: this = this * ss2
+
+ This is Karatsuba Multiplication algorithm, we're using it when value_size is greater than
+ or equal to TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE macro (defined in ttmathuint.h).
+ If value_size is smaller then we're using Mul2Big() instead.
+
+ Karatsuba multiplication:
+ Assume we have:
+ this = x = x1*B^m + x0
+ ss2 = y = y1*B^m + y0
+ where x0 and y0 are less than B^m
+ the product from multiplication we can show as:
+ x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
+ where
+ z2 = x1*y1
+ z1 = x1*y0 + x0*y1
+ z0 = x0*y0
+ this is standard schoolbook algorithm with O(n^2), Karatsuba observed that z1 can be given in other form:
+ z1 = (x1 + x0)*(y1 + y0) - z2 - z0 / z1 = (x1*y1 + x1*y0 + x0*y1 + x0*y0) - x1*y1 - x0*y0 = x1*y0 + x0*y1 /
+ and to calculate the multiplication we need only three multiplications (with some additions and subtractions)
+
+ Our objects 'this' and 'ss2' we divide into two parts and by using recurrence we calculate the multiplication.
+ Karatsuba multiplication has O( n^(ln(3)/ln(2)) )
+ */
+ uint Mul3(const UInt<value_size> & ss2)
+ {
+ UInt<value_size*2> result;
+ uint i, c = 0;
+
+ Mul3Big(ss2, result);
+
+ // copying result
+ for(i=0 ; i<value_size ; ++i)
+ table[i] = result.table[i];
+
+ // testing carry
+ for( ; i<value_size*2 ; ++i)
+ if( result.table[i] != 0 )
+ {
+ c = 1;
+ break;
+ }
+
+ TTMATH_LOGC("UInt::Mul3", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ multiplication: result = this * ss2
+
+ result is twice bigger than this and ss2,
+ this method never returns carry,
+ (Karatsuba multiplication)
+ */
+ void Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
+ {
+ Mul3Big2<value_size>(table, ss2.table, result.table);
+
+ TTMATH_LOG("UInt::Mul3Big")
+ }
+
+
+
+private:
+
+ /*!
+ an auxiliary method for calculating the Karatsuba multiplication
+
+ result_size is equal ss_size*2
+ */
+ template<uint ss_size>
+ void Mul3Big2(const uint * ss1, const uint * ss2, uint * result)
+ {
+ const uint * x1, * x0, * y1, * y0;
+
+
+ if( ss_size>1 && ss_size<TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
+ {
+ UInt<ss_size*2> res;
+ Mul2Big2<ss_size>(ss1, ss2, res);
+
+ for(uint i=0 ; i<ss_size*2 ; ++i)
+ result[i] = res.table[i];
+
+ return;
+ }
+ else
+ if( ss_size == 1 )
+ {
+ return MulTwoWords(*ss1, *ss2, &result[1], &result[0]);
+ }
+
+
+ if( (ss_size & 1) == 1 )
+ {
+ // ss_size is odd
+ x0 = ss1;
+ y0 = ss2;
+ x1 = ss1 + ss_size / 2 + 1;
+ y1 = ss2 + ss_size / 2 + 1;
+
+ // the second vectors (x1 and y1) are smaller about one from the first ones (x0 and y0)
+ Mul3Big3<ss_size/2 + 1, ss_size/2, ss_size*2>(x1, x0, y1, y0, result);
+ }
+ else
+ {
+ // ss_size is even
+ x0 = ss1;
+ y0 = ss2;
+ x1 = ss1 + ss_size / 2;
+ y1 = ss2 + ss_size / 2;
+
+ // all four vectors (x0 x1 y0 y1) are equal in size
+ Mul3Big3<ss_size/2, ss_size/2, ss_size*2>(x1, x0, y1, y0, result);
+ }
+ }
+
+
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4717)
+//warning C4717: recursive on all control paths, function will cause runtime stack overflow
+//we have the stop point in Mul3Big2() method
+#endif
+
+
+ /*!
+ an auxiliary method for calculating the Karatsuba multiplication
+
+ x = x1*B^m + x0
+ y = y1*B^m + y0
+
+ first_size - is the size of vectors: x0 and y0
+ second_size - is the size of vectors: x1 and y1 (can be either equal first_size or smaller about one from first_size)
+
+ x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
+ where
+ z0 = x0*y0
+ z2 = x1*y1
+ z1 = (x1 + x0)*(y1 + y0) - z2 - z0
+ */
+ template<uint first_size, uint second_size, uint result_size>
+ void Mul3Big3(const uint * x1, const uint * x0, const uint * y1, const uint * y0, uint * result)
+ {
+ uint i, c, xc, yc;
+
+ UInt<first_size> temp, temp2;
+ UInt<first_size*3> z1;
+
+ // z0 and z2 we store directly in the result (we don't use any temporary variables)
+ Mul3Big2<first_size>(x0, y0, result); // z0
+ Mul3Big2<second_size>(x1, y1, result+first_size*2); // z2
+
+ // now we calculate z1
+ // temp = (x0 + x1)
+ // temp2 = (y0 + y1)
+ // we're using temp and temp2 with UInt<first_size>, although there can be a carry but
+ // we simple remember it in xc and yc (xc and yc can be either 0 or 1),
+ // and (x0 + x1)*(y0 + y1) we calculate in this way (schoolbook algorithm):
+ //
+ // xc | temp
+ // yc | temp2
+ // --------------------
+ // (temp * temp2)
+ // xc*temp2 |
+ // yc*temp |
+ // xc*yc |
+ // ---------- z1 --------
+ //
+ // and the result is never larger in size than 3*first_size
+
+ xc = AddVector(x0, x1, first_size, second_size, temp.table);
+ yc = AddVector(y0, y1, first_size, second_size, temp2.table);
+
+ Mul3Big2<first_size>(temp.table, temp2.table, z1.table);
+
+ // clearing the rest of z1
+ for(i=first_size*2 ; i<first_size*3 ; ++i)
+ z1.table[i] = 0;
+
+
+ if( xc )
+ {
+ c = AddVector(z1.table+first_size, temp2.table, first_size*3-first_size, first_size, z1.table+first_size);
+ TTMATH_ASSERT( c==0 )
+ }
+
+ if( yc )
+ {
+ c = AddVector(z1.table+first_size, temp.table, first_size*3-first_size, first_size, z1.table+first_size);
+ TTMATH_ASSERT( c==0 )
+ }
+
+
+ if( xc && yc )
+ {
+ for( i=first_size*2 ; i<first_size*3 ; ++i )
+ if( ++z1.table[i] != 0 )
+ break; // break if there was no carry
+ }
+
+ // z1 = z1 - z2
+ c = SubVector(z1.table, result+first_size*2, first_size*3, second_size*2, z1.table);
+ TTMATH_ASSERT(c==0)
+
+ // z1 = z1 - z0
+ c = SubVector(z1.table, result, first_size*3, first_size*2, z1.table);
+ TTMATH_ASSERT(c==0)
+
+ // here we've calculated the z1
+ // now we're adding it to the result
+
+ if( first_size > second_size )
+ {
+ uint z1_size = result_size - first_size;
+ TTMATH_ASSERT( z1_size <= first_size*3 )
+
+ for(i=z1_size ; i<first_size*3 ; ++i)
+ {
+ TTMATH_ASSERT( z1.table[i] == 0 )
+ }
+
+ c = AddVector(result+first_size, z1.table, result_size-first_size, z1_size, result+first_size);
+ TTMATH_ASSERT(c==0)
+ }
+ else
+ {
+ c = AddVector(result+first_size, z1.table, result_size-first_size, first_size*3, result+first_size);
+ TTMATH_ASSERT(c==0)
+ }
+ }
+
+
+
+#ifdef _MSC_VER
+#pragma warning (default : 4717)
+#endif
+
+
+public:
+
+
+ /*!
+ multiplication this = this * ss2
+ */
+ uint MulFastest(const UInt<value_size> & ss2)
+ {
+ UInt<value_size*2> result;
+ uint i, c = 0;
+
+ MulFastestBig(ss2, result);
+
+ // copying result
+ for(i=0 ; i<value_size ; ++i)
+ table[i] = result.table[i];
+
+ // testing carry
+ for( ; i<value_size*2 ; ++i)
+ if( result.table[i] != 0 )
+ {
+ c = 1;
+ break;
+ }
+
+ TTMATH_LOGC("UInt::MulFastest", c)
+
+ return c;
+ }
+
+
+ /*!
+ multiplication result = this * ss2
+
+ this method is trying to select the fastest algorithm
+ (in the future this method can be improved)
+ */
+ void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
+ {
+ if( value_size < TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
+ return Mul2Big(ss2, result);
+
+ uint x1size = value_size, x2size = value_size;
+ uint x1start = 0, x2start = 0;
+
+ for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
+ for(x2size=value_size ; x2size>0 && ss2.table[x2size-1]==0 ; --x2size);
+
+ if( x1size==0 || x2size==0 )
+ {
+ // either 'this' or 'ss2' is equal zero - the result is zero too
+ result.SetZero();
+ return;
+ }
+
+ for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
+ for(x2start=0 ; x2start<x2size && ss2.table[x2start]==0 ; ++x2start);
+
+ uint distancex1 = x1size - x1start;
+ uint distancex2 = x2size - x2start;
+
+ if( distancex1 < 3 || distancex2 < 3 )
+ // either 'this' or 'ss2' have only 2 (or 1) items different from zero (side by side)
+ // (this condition in the future can be improved)
+ return Mul2Big3<value_size>(table, ss2.table, result, x1start, x1size, x2start, x2size);
+
+
+ // Karatsuba multiplication
+ Mul3Big(ss2, result);
+
+ TTMATH_LOG("UInt::MulFastestBig")
+ }
+
+
+ /*!
+ *
+ * Division
+ *
+ *
+ */
+
+public:
+
+
+ /*!
+ division by one unsigned word
+
+ returns 1 when divisor is zero
+ */
+ uint DivInt(uint divisor, uint * remainder = 0)
+ {
+ if( divisor == 0 )
+ {
+ if( remainder )
+ *remainder = 0; // this is for convenience, without it the compiler can report that 'remainder' is uninitialized
+
+ TTMATH_LOG("UInt::DivInt")
+
+ return 1;
+ }
+
+ if( divisor == 1 )
+ {
+ if( remainder )
+ *remainder = 0;
+
+ TTMATH_LOG("UInt::DivInt")
+
+ return 0;
+ }
+
+ UInt<value_size> dividend(*this);
+ SetZero();
+
+ sint i; // i must be with a sign
+ uint r = 0;
+
+ // we're looking for the last word in ss1
+ for(i=value_size-1 ; i>0 && dividend.table[i]==0 ; --i);
+
+ for( ; i>=0 ; --i)
+ DivTwoWords(r, dividend.table[i], divisor, &table[i], &r);
+
+ if( remainder )
+ *remainder = r;
+
+ TTMATH_LOG("UInt::DivInt")
+
+ return 0;
+ }
+
+ uint DivInt(uint divisor, uint & remainder)
+ {
+ return DivInt(divisor, &remainder);
+ }
+
+
+
+ /*!
+ division this = this / ss2
+
+ return values:
+ 0 - ok
+ 1 - division by zero
+ 'this' will be the quotient
+ 'remainder' - remainder
+ */
+ uint Div( const UInt<value_size> & divisor,
+ UInt<value_size> * remainder = 0,
+ uint algorithm = 3)
+ {
+ switch( algorithm )
+ {
+ case 1:
+ return Div1(divisor, remainder);
+
+ case 2:
+ return Div2(divisor, remainder);
+
+ case 3:
+ default:
+ return Div3(divisor, remainder);
+ }
+ }
+
+ uint Div(const UInt<value_size> & divisor, UInt<value_size> & remainder, uint algorithm = 3)
+ {
+ return Div(divisor, &remainder, algorithm);
+ }
+
+
+
+private:
+
+ /*!
+ return values:
+ 0 - none has to be done
+ 1 - division by zero
+ 2 - division should be made
+ */
+ uint Div_StandardTest( const UInt<value_size> & v,
+ uint & m, uint & n,
+ UInt<value_size> * remainder = 0)
+ {
+ switch( Div_CalculatingSize(v, m, n) )
+ {
+ case 4: // 'this' is equal v
+ if( remainder )
+ remainder->SetZero();
+
+ SetOne();
+ TTMATH_LOG("UInt::Div_StandardTest")
+ return 0;
+
+ case 3: // 'this' is smaller than v
+ if( remainder )
+ *remainder = *this;
+
+ SetZero();
+ TTMATH_LOG("UInt::Div_StandardTest")
+ return 0;
+
+ case 2: // 'this' is zero
+ if( remainder )
+ remainder->SetZero();
+
+ SetZero();
+ TTMATH_LOG("UInt::Div_StandardTest")
+ return 0;
+
+ case 1: // v is zero
+ TTMATH_LOG("UInt::Div_StandardTest")
+ return 1;
+ }
+
+ TTMATH_LOG("UInt::Div_StandardTest")
+
+ return 2;
+ }
+
+
+
+ /*!
+ return values:
+ 0 - ok
+ 'm' - is the index (from 0) of last non-zero word in table ('this')
+ 'n' - is the index (from 0) of last non-zero word in v.table
+ 1 - v is zero
+ 2 - 'this' is zero
+ 3 - 'this' is smaller than v
+ 4 - 'this' is equal v
+
+ if the return value is different than zero the 'm' and 'n' are undefined
+ */
+ uint Div_CalculatingSize(const UInt<value_size> & v, uint & m, uint & n)
+ {
+ m = n = value_size-1;
+
+ for( ; n!=0 && v.table[n]==0 ; --n);
+
+ if( n==0 && v.table[n]==0 )
+ return 1;
+
+ for( ; m!=0 && table[m]==0 ; --m);
+
+ if( m==0 && table[m]==0 )
+ return 2;
+
+ if( m < n )
+ return 3;
+ else
+ if( m == n )
+ {
+ uint i;
+ for(i = n ; i!=0 && table[i]==v.table[i] ; --i);
+
+ if( table[i] < v.table[i] )
+ return 3;
+ else
+ if (table[i] == v.table[i] )
+ return 4;
+ }
+
+ return 0;
+ }
+
+
+public:
+
+ /*!
+ the first division algorithm
+ radix 2
+ */
+ uint Div1(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
+ {
+ uint m,n, test;
+
+ test = Div_StandardTest(divisor, m, n, remainder);
+ if( test < 2 )
+ return test;
+
+ if( !remainder )
+ {
+ UInt<value_size> rem;
+
+ return Div1_Calculate(divisor, rem);
+ }
+
+ return Div1_Calculate(divisor, *remainder);
+ }
+
+
+ /*!
+ the first division algorithm
+ radix 2
+ */
+ uint Div1(const UInt<value_size> & divisor, UInt<value_size> & remainder)
+ {
+ return Div1(divisor, &remainder);
+ }
+
+
+private:
+
+ uint Div1_Calculate(const UInt<value_size> & divisor, UInt<value_size> & rest)
+ {
+ if( this == &divisor )
+ {
+ UInt<value_size> divisor_copy(divisor);
+ return Div1_CalculateRef(divisor_copy, rest);
+ }
+ else
+ {
+ return Div1_CalculateRef(divisor, rest);
+ }
+ }
+
+
+ uint Div1_CalculateRef(const UInt<value_size> & divisor, UInt<value_size> & rest)
+ {
+ TTMATH_REFERENCE_ASSERT( divisor )
+
+ sint loop;
+ sint c;
+
+ rest.SetZero();
+ loop = value_size * TTMATH_BITS_PER_UINT;
+ c = 0;
+
+
+ div_a:
+ c = Rcl(1, c);
+ c = rest.Add(rest,c);
+ c = rest.Sub(divisor,c);
+
+ c = !c;
+
+ if(!c)
+ goto div_d;
+
+
+ div_b:
+ --loop;
+ if(loop)
+ goto div_a;
+
+ c = Rcl(1, c);
+ TTMATH_LOG("UInt::Div1_Calculate")
+ return 0;
+
+
+ div_c:
+ c = Rcl(1, c);
+ c = rest.Add(rest,c);
+ c = rest.Add(divisor);
+
+ if(c)
+ goto div_b;
+
+
+ div_d:
+ --loop;
+ if(loop)
+ goto div_c;
+
+ c = Rcl(1, c);
+ c = rest.Add(divisor);
+
+ TTMATH_LOG("UInt::Div1_Calculate")
+
+ return 0;
+ }
+
+
+public:
+
+ /*!
+ the second division algorithm
+
+ return values:
+ 0 - ok
+ 1 - division by zero
+ */
+ uint Div2(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
+ {
+ if( this == &divisor )
+ {
+ UInt<value_size> divisor_copy(divisor);
+ return Div2Ref(divisor_copy, remainder);
+ }
+ else
+ {
+ return Div2Ref(divisor, remainder);
+ }
+ }
+
+
+ /*!
+ the second division algorithm
+
+ return values:
+ 0 - ok
+ 1 - division by zero
+ */
+ uint Div2(const UInt<value_size> & divisor, UInt<value_size> & remainder)
+ {
+ return Div2(divisor, &remainder);
+ }
+
+
+private:
+
+ /*!
+ the second division algorithm
+
+ return values:
+ 0 - ok
+ 1 - division by zero
+ */
+ uint Div2Ref(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
+ {
+ uint bits_diff;
+ uint status = Div2_Calculate(divisor, remainder, bits_diff);
+ if( status < 2 )
+ return status;
+
+ if( CmpBiggerEqual(divisor) )
+ {
+ Div2(divisor, remainder);
+ SetBit(bits_diff);
+ }
+ else
+ {
+ if( remainder )
+ *remainder = *this;
+
+ SetZero();
+ SetBit(bits_diff);
+ }
+
+ TTMATH_LOG("UInt::Div2")
+
+ return 0;
+ }
+
+
+ /*!
+ return values:
+ 0 - we've calculated the division
+ 1 - division by zero
+ 2 - we have to still calculate
+
+ */
+ uint Div2_Calculate(const UInt<value_size> & divisor, UInt<value_size> * remainder,
+ uint & bits_diff)
+ {
+ uint table_id, index;
+ uint divisor_table_id, divisor_index;
+
+ uint status = Div2_FindLeadingBitsAndCheck( divisor, remainder,
+ table_id, index,
+ divisor_table_id, divisor_index);
+
+ if( status < 2 )
+ {
+ TTMATH_LOG("UInt::Div2_Calculate")
+ return status;
+ }
+
+ // here we know that 'this' is greater than divisor
+ // then 'index' is greater or equal 'divisor_index'
+ bits_diff = index - divisor_index;
+
+ UInt<value_size> divisor_copy(divisor);
+ divisor_copy.Rcl(bits_diff, 0);
+
+ if( CmpSmaller(divisor_copy, table_id) )
+ {
+ divisor_copy.Rcr(1);
+ --bits_diff;
+ }
+
+ Sub(divisor_copy, 0);
+
+ TTMATH_LOG("UInt::Div2_Calculate")
+
+ return 2;
+ }
+
+
+ /*!
+ return values:
+ 0 - we've calculated the division
+ 1 - division by zero
+ 2 - we have to still calculate
+ */
+ uint Div2_FindLeadingBitsAndCheck( const UInt<value_size> & divisor,
+ UInt<value_size> * remainder,
+ uint & table_id, uint & index,
+ uint & divisor_table_id, uint & divisor_index)
+ {
+ if( !divisor.FindLeadingBit(divisor_table_id, divisor_index) )
+ {
+ // division by zero
+ TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+ return 1;
+ }
+
+ if( !FindLeadingBit(table_id, index) )
+ {
+ // zero is divided by something
+
+ SetZero();
+
+ if( remainder )
+ remainder->SetZero();
+
+ TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+
+ return 0;
+ }
+
+ divisor_index += divisor_table_id * TTMATH_BITS_PER_UINT;
+ index += table_id * TTMATH_BITS_PER_UINT;
+
+ if( divisor_table_id == 0 )
+ {
+ // dividor has only one 32-bit word
+
+ uint r;
+ DivInt(divisor.table[0], &r);
+
+ if( remainder )
+ {
+ remainder->SetZero();
+ remainder->table[0] = r;
+ }
+
+ TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+
+ return 0;
+ }
+
+
+ if( Div2_DivisorGreaterOrEqual( divisor, remainder,
+ table_id, index,
+ divisor_index) )
+ {
+ TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+ return 0;
+ }
+
+
+ TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+
+ return 2;
+ }
+
+
+ /*!
+ return values:
+ true if divisor is equal or greater than 'this'
+ */
+ bool Div2_DivisorGreaterOrEqual( const UInt<value_size> & divisor,
+ UInt<value_size> * remainder,
+ uint table_id, uint index,
+ uint divisor_index )
+ {
+ if( divisor_index > index )
+ {
+ // divisor is greater than this
+
+ if( remainder )
+ *remainder = *this;
+
+ SetZero();
+
+ TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
+
+ return true;
+ }
+
+ if( divisor_index == index )
+ {
+ // table_id == divisor_table_id as well
+
+ uint i;
+ for(i = table_id ; i!=0 && table[i]==divisor.table[i] ; --i);
+
+ if( table[i] < divisor.table[i] )
+ {
+ // divisor is greater than 'this'
+
+ if( remainder )
+ *remainder = *this;
+
+ SetZero();
+
+ TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
+
+ return true;
+ }
+ else
+ if( table[i] == divisor.table[i] )
+ {
+ // divisor is equal 'this'
+
+ if( remainder )
+ remainder->SetZero();
+
+ SetOne();
+
+ TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
+
+ return true;
+ }
+ }
+
+ TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
+
+ return false;
+ }
+
+
+public:
+
+ /*!
+ the third division algorithm
+ */
+ uint Div3(const UInt<value_size> & ss2, UInt<value_size> * remainder = 0)
+ {
+ if( this == &ss2 )
+ {
+ UInt<value_size> copy_ss2(ss2);
+ return Div3Ref(copy_ss2, remainder);
+ }
+ else
+ {
+ return Div3Ref(ss2, remainder);
+ }
+ }
+
+
+ /*!
+ the third division algorithm
+ */
+ uint Div3(const UInt<value_size> & ss2, UInt<value_size> & remainder)
+ {
+ return Div3(ss2, &remainder);
+ }
+
+
+private:
+
+ /*!
+ the third division algorithm
+
+ this algorithm is described in the following book:
+ "The art of computer programming 2" (4.3.1 page 272)
+ Donald E. Knuth
+ !! give the description here (from the book)
+ */
+ uint Div3Ref(const UInt<value_size> & v, UInt<value_size> * remainder = 0)
+ {
+ uint m,n, test;
+
+ test = Div_StandardTest(v, m, n, remainder);
+ if( test < 2 )
+ return test;
+
+ if( n == 0 )
+ {
+ uint r;
+ DivInt( v.table[0], &r );
+
+ if( remainder )
+ {
+ remainder->SetZero();
+ remainder->table[0] = r;
+ }
+
+ TTMATH_LOG("UInt::Div3")
+
+ return 0;
+ }
+
+
+ // we can only use the third division algorithm when
+ // the divisor is greater or equal 2^32 (has more than one 32-bit word)
+ ++m;
+ ++n;
+ m = m - n;
+ Div3_Division(v, remainder, m, n);
+
+ TTMATH_LOG("UInt::Div3")
+
+ return 0;
+ }
+
+
+
+private:
+
+
+ void Div3_Division(UInt<value_size> v, UInt<value_size> * remainder, uint m, uint n)
+ {
+ TTMATH_ASSERT( n>=2 )
+
+ UInt<value_size+1> uu, vv;
+ UInt<value_size> q;
+ uint d, u_value_size, u0, u1, u2, v1, v0, j=m;
+
+ u_value_size = Div3_Normalize(v, n, d);
+
+ if( j+n == value_size )
+ u2 = u_value_size;
+ else
+ u2 = table[j+n];
+
+ Div3_MakeBiggerV(v, vv);
+
+ for(uint i = j+1 ; i<value_size ; ++i)
+ q.table[i] = 0;
+
+ while( true )
+ {
+ u1 = table[j+n-1];
+ u0 = table[j+n-2];
+ v1 = v.table[n-1];
+ v0 = v.table[n-2];
+
+ uint qp = Div3_Calculate(u2,u1,u0, v1,v0);
+
+ Div3_MakeNewU(uu, j, n, u2);
+ Div3_MultiplySubtract(uu, vv, qp);
+ Div3_CopyNewU(uu, j, n);
+
+ q.table[j] = qp;
+
+ // the next loop
+ if( j-- == 0 )
+ break;
+
+ u2 = table[j+n];
+ }
+
+ if( remainder )
+ Div3_Unnormalize(remainder, n, d);
+
+ *this = q;
+
+ TTMATH_LOG("UInt::Div3_Division")
+ }
+
+
+ void Div3_MakeNewU(UInt<value_size+1> & uu, uint j, uint n, uint u_max)
+ {
+ uint i;
+
+ for(i=0 ; i<n ; ++i, ++j)
+ uu.table[i] = table[j];
+
+ // 'n' is from <1..value_size> so and 'i' is from <0..value_size>
+ // then table[i] is always correct (look at the declaration of 'uu')
+ uu.table[i] = u_max;
+
+ for( ++i ; i<value_size+1 ; ++i)
+ uu.table[i] = 0;
+
+ TTMATH_LOG("UInt::Div3_MakeNewU")
+ }
+
+
+ void Div3_CopyNewU(const UInt<value_size+1> & uu, uint j, uint n)
+ {
+ uint i;
+
+ for(i=0 ; i<n ; ++i)
+ table[i+j] = uu.table[i];
+
+ if( i+j < value_size )
+ table[i+j] = uu.table[i];
+
+ TTMATH_LOG("UInt::Div3_CopyNewU")
+ }
+
+
+ /*!
+ we're making the new 'vv'
+ the value is actually the same but the 'table' is bigger (value_size+1)
+ */
+ void Div3_MakeBiggerV(const UInt<value_size> & v, UInt<value_size+1> & vv)
+ {
+ for(uint i=0 ; i<value_size ; ++i)
+ vv.table[i] = v.table[i];
+
+ vv.table[value_size] = 0;
+
+ TTMATH_LOG("UInt::Div3_MakeBiggerV")
+ }
+
+
+ /*!
+ we're moving all bits from 'v' into the left side of the n-1 word
+ (the highest bit at v.table[n-1] will be equal one,
+ the bits from 'this' we're moving the same times as 'v')
+
+ return values:
+ d - how many times we've moved
+ return - the next-left value from 'this' (that after table[value_size-1])
+ */
+ uint Div3_Normalize(UInt<value_size> & v, uint n, uint & d)
+ {
+ // v.table[n-1] is != 0
+
+ uint bit = (uint)FindLeadingBitInWord(v.table[n-1]);
+ uint move = (TTMATH_BITS_PER_UINT - bit - 1);
+ uint res = table[value_size-1];
+ d = move;
+
+ if( move > 0 )
+ {
+ v.Rcl(move, 0);
+ Rcl(move, 0);
+ res = res >> (bit + 1);
+ }
+ else
+ {
+ res = 0;
+ }
+
+ TTMATH_LOG("UInt::Div3_Normalize")
+
+ return res;
+ }
+
+
+ void Div3_Unnormalize(UInt<value_size> * remainder, uint n, uint d)
+ {
+ for(uint i=n ; i<value_size ; ++i)
+ table[i] = 0;
+
+ Rcr(d,0);
+
+ *remainder = *this;
+
+ TTMATH_LOG("UInt::Div3_Unnormalize")
+ }
+
+
+ uint Div3_Calculate(uint u2, uint u1, uint u0, uint v1, uint v0)
+ {
+ UInt<2> u_temp;
+ uint rp;
+ bool next_test;
+
+ TTMATH_ASSERT( v1 != 0 )
+
+ u_temp.table[1] = u2;
+ u_temp.table[0] = u1;
+ u_temp.DivInt(v1, &rp);
+
+ TTMATH_ASSERT( u_temp.table[1]==0 || u_temp.table[1]==1 )
+
+ do
+ {
+ bool decrease = false;
+
+ if( u_temp.table[1] == 1 )
+ decrease = true;
+ else
+ {
+ UInt<2> temp1, temp2;
+
+ UInt<2>::MulTwoWords(u_temp.table[0], v0, temp1.table+1, temp1.table);
+ temp2.table[1] = rp;
+ temp2.table[0] = u0;
+
+ if( temp1 > temp2 )
+ decrease = true;
+ }
+
+ next_test = false;
+
+ if( decrease )
+ {
+ u_temp.SubOne();
+
+ rp += v1;
+
+ if( rp >= v1 ) // it means that there wasn't a carry (r<b from the book)
+ next_test = true;
+ }
+ }
+ while( next_test );
+
+ TTMATH_LOG("UInt::Div3_Calculate")
+
+ return u_temp.table[0];
+ }
+
+
+
+ void Div3_MultiplySubtract( UInt<value_size+1> & uu,
+ const UInt<value_size+1> & vv, uint & qp)
+ {
+ // D4 (in the book)
+
+ UInt<value_size+1> vv_temp(vv);
+ vv_temp.MulInt(qp);
+
+ if( uu.Sub(vv_temp) )
+ {
+ // there was a carry
+
+ //
+ // !!! this part of code was not tested
+ //
+
+ --qp;
+ uu.Add(vv);
+
+ // can be a carry from this additions but it should be ignored
+ // because it cancels with the borrow from uu.Sub(vv_temp)
+ }
+
+ TTMATH_LOG("UInt::Div3_MultiplySubtract")
+ }
+
+
+
+
+
+
+public:
+
+
+ /*!
+ power this = this ^ pow
+ binary algorithm (r-to-l)
+
+ return values:
+ 0 - ok
+ 1 - carry
+ 2 - incorrect argument (0^0)
+ */
+ uint Pow(UInt<value_size> pow)
+ {
+ if(pow.IsZero() && IsZero())
+ // we don't define zero^zero
+ return 2;
+
+ UInt<value_size> start(*this);
+ UInt<value_size> result;
+ result.SetOne();
+ uint c = 0;
+
+ while( !c )
+ {
+ if( pow.table[0] & 1 )
+ c += result.Mul(start);
+
+ pow.Rcr2_one(0);
+ if( pow.IsZero() )
+ break;
+
+ c += start.Mul(start);
+ }
+
+ *this = result;
+
+ TTMATH_LOGC("UInt::Pow(UInt<>)", c)
+
+ return (c==0)? 0 : 1;
+ }
+
+
+ /*!
+ square root
+ e.g. Sqrt(9) = 3
+ ('digit-by-digit' algorithm)
+ */
+ void Sqrt()
+ {
+ UInt<value_size> bit, temp;
+
+ if( IsZero() )
+ return;
+
+ UInt<value_size> value(*this);
+
+ SetZero();
+ bit.SetZero();
+ bit.table[value_size-1] = (TTMATH_UINT_HIGHEST_BIT >> 1);
+
+ while( bit > value )
+ bit.Rcr(2);
+
+ while( !bit.IsZero() )
+ {
+ temp = *this;
+ temp.Add(bit);
+
+ if( value >= temp )
+ {
+ value.Sub(temp);
+ Rcr(1);
+ Add(bit);
+ }
+ else
+ {
+ Rcr(1);
+ }
+
+ bit.Rcr(2);
+ }
+
+ TTMATH_LOG("UInt::Sqrt")
+ }
+
+
+
+ /*!
+ this method sets n first bits to value zero
+
+ For example:
+ let n=2 then if there's a value 111 (bin) there'll be '100' (bin)
+ */
+ void ClearFirstBits(uint n)
+ {
+ if( n >= value_size*TTMATH_BITS_PER_UINT )
+ {
+ SetZero();
+ TTMATH_LOG("UInt::ClearFirstBits")
+ return;
+ }
+
+ uint * p = table;
+
+ // first we're clearing the whole words
+ while( n >= TTMATH_BITS_PER_UINT )
+ {
+ *p++ = 0;
+ n -= TTMATH_BITS_PER_UINT;
+ }
+
+ if( n == 0 )
+ {
+ TTMATH_LOG("UInt::ClearFirstBits")
+ return;
+ }
+
+ // and then we're clearing one word which has left
+ // mask -- all bits are set to one
+ uint mask = TTMATH_UINT_MAX_VALUE;
+
+ mask = mask << n;
+
+ (*p) &= mask;
+
+ TTMATH_LOG("UInt::ClearFirstBits")
+ }
+
+
+ /*!
+ this method returns true if the highest bit of the value is set
+ */
+ bool IsTheHighestBitSet() const
+ {
+ return (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) != 0;
+ }
+
+
+ /*!
+ this method returns true if the lowest bit of the value is set
+ */
+ bool IsTheLowestBitSet() const
+ {
+ return (*table & 1) != 0;
+ }
+
+
+ /*!
+ returning true if only the highest bit is set
+ */
+ bool IsOnlyTheHighestBitSet() const
+ {
+ for(uint i=0 ; i<value_size-1 ; ++i)
+ if( table[i] != 0 )
+ return false;
+
+ if( table[value_size-1] != TTMATH_UINT_HIGHEST_BIT )
+ return false;
+
+ return true;
+ }
+
+
+ /*!
+ returning true if only the lowest bit is set
+ */
+ bool IsOnlyTheLowestBitSet() const
+ {
+ if( table[0] != 1 )
+ return false;
+
+ for(uint i=1 ; i<value_size ; ++i)
+ if( table[i] != 0 )
+ return false;
+
+ return true;
+ }
+
+
+ /*!
+ this method returns true if the value is equal zero
+ */
+ bool IsZero() const
+ {
+ for(uint i=0 ; i<value_size ; ++i)
+ if(table[i] != 0)
+ return false;
+
+ return true;
+ }
+
+
+ /*!
+ returning true if first 'bits' bits are equal zero
+ */
+ bool AreFirstBitsZero(uint bits) const
+ {
+ TTMATH_ASSERT( bits <= value_size * TTMATH_BITS_PER_UINT )
+
+ uint index = bits / TTMATH_BITS_PER_UINT;
+ uint rest = bits % TTMATH_BITS_PER_UINT;
+ uint i;
+
+ for(i=0 ; i<index ; ++i)
+ if(table[i] != 0 )
+ return false;
+
+ if( rest == 0 )
+ return true;
+
+ uint mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
+
+ return (table[i] & mask) == 0;
+ }
+
+
+
+ /*!
+ *
+ * conversion methods
+ *
+ */
+
+
+
+ /*!
+ this method converts an UInt<another_size> type to this class
+
+ this operation has mainly sense if the value from p is
+ equal or smaller than that one which is returned from UInt<value_size>::SetMax()
+
+ it returns a carry if the value 'p' is too big
+ */
+ template<uint argument_size>
+ uint FromUInt(const UInt<argument_size> & p)
+ {
+ uint min_size = (value_size < argument_size)? value_size : argument_size;
+ uint i;
+
+ for(i=0 ; i<min_size ; ++i)
+ table[i] = p.table[i];
+
+
+ if( value_size > argument_size )
+ {
+ // 'this' is longer than 'p'
+
+ for( ; i<value_size ; ++i)
+ table[i] = 0;
+ }
+ else
+ {
+ for( ; i<argument_size ; ++i)
+ if( p.table[i] != 0 )
+ {
+ TTMATH_LOGC("UInt::FromUInt(UInt<>)", 1)
+ return 1;
+ }
+ }
+
+ TTMATH_LOGC("UInt::FromUInt(UInt<>)", 0)
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts an UInt<another_size> type to this class
+
+ this operation has mainly sense if the value from p is
+ equal or smaller than that one which is returned from UInt<value_size>::SetMax()
+
+ it returns a carry if the value 'p' is too big
+ */
+ template<uint argument_size>
+ uint FromInt(const UInt<argument_size> & p)
+ {
+ return FromUInt(p);
+ }
+
+
+ /*!
+ this method converts the uint type to this class
+ */
+ uint FromUInt(uint value)
+ {
+ for(uint i=1 ; i<value_size ; ++i)
+ table[i] = 0;
+
+ table[0] = value;
+
+ TTMATH_LOG("UInt::FromUInt(uint)")
+
+ // there'll never be a carry here
+ return 0;
+ }
+
+
+ /*!
+ this method converts the uint type to this class
+ */
+ uint FromInt(uint value)
+ {
+ return FromUInt(value);
+ }
+
+
+ /*!
+ this method converts the sint type to this class
+ */
+ uint FromInt(sint value)
+ {
+ uint c = FromUInt(uint(value));
+
+ if( c || value < 0 )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this operator converts an UInt<another_size> type to this class
+
+ it doesn't return a carry
+ */
+ template<uint argument_size>
+ UInt<value_size> & operator=(const UInt<argument_size> & p)
+ {
+ FromUInt(p);
+
+ return *this;
+ }
+
+
+ /*!
+ the assignment operator
+ */
+ UInt<value_size> & operator=(const UInt<value_size> & p)
+ {
+ for(uint i=0 ; i<value_size ; ++i)
+ table[i] = p.table[i];
+
+ TTMATH_LOG("UInt::operator=(UInt<>)")
+
+ return *this;
+ }
+
+
+ /*!
+ this method converts the uint type to this class
+ */
+ UInt<value_size> & operator=(uint i)
+ {
+ FromUInt(i);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting the uint to this class
+ */
+ UInt(uint i)
+ {
+ FromUInt(i);
+ }
+
+
+ /*!
+ this method converts the sint type to this class
+ */
+ UInt<value_size> & operator=(sint i)
+ {
+ FromInt(i);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting the sint to this class
+
+ look at the description of UInt::operator=(sint)
+ */
+ UInt(sint i)
+ {
+ FromInt(i);
+ }
+
+
+#ifdef TTMATH_PLATFORM32
+
+
+ /*!
+ this method converts unsigned 64 bit int type to this class
+ ***this method is created only on a 32bit platform***
+ */
+ uint FromUInt(ulint n)
+ {
+ table[0] = (uint)n;
+
+ if( value_size == 1 )
+ {
+ uint c = ((n >> TTMATH_BITS_PER_UINT) == 0) ? 0 : 1;
+
+ TTMATH_LOGC("UInt::FromUInt(ulint)", c)
+ return c;
+ }
+
+ table[1] = (uint)(n >> TTMATH_BITS_PER_UINT);
+
+ for(uint i=2 ; i<value_size ; ++i)
+ table[i] = 0;
+
+ TTMATH_LOG("UInt::FromUInt(ulint)")
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts unsigned 64 bit int type to this class
+ ***this method is created only on a 32bit platform***
+ */
+ uint FromInt(ulint n)
+ {
+ return FromUInt(n);
+ }
+
+
+ /*!
+ this method converts signed 64 bit int type to this class
+ ***this method is created only on a 32bit platform***
+ */
+ uint FromInt(slint n)
+ {
+ uint c = FromUInt(ulint(n));
+
+ if( c || n < 0 )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this operator converts unsigned 64 bit int type to this class
+ ***this operator is created only on a 32bit platform***
+ */
+ UInt<value_size> & operator=(ulint n)
+ {
+ FromUInt(n);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting unsigned 64 bit int to this class
+ ***this constructor is created only on a 32bit platform***
+ */
+ UInt(ulint n)
+ {
+ FromUInt(n);
+ }
+
+
+ /*!
+ this operator converts signed 64 bit int type to this class
+ ***this operator is created only on a 32bit platform***
+ */
+ UInt<value_size> & operator=(slint n)
+ {
+ FromInt(n);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting signed 64 bit int to this class
+ ***this constructor is created only on a 32bit platform***
+ */
+ UInt(slint n)
+ {
+ FromInt(n);
+ }
+
+#endif
+
+
+
+#ifdef TTMATH_PLATFORM64
+
+
+ /*!
+ this method converts 32 bit unsigned int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ uint FromUInt(unsigned int i)
+ {
+ return FromUInt(uint(i));
+ }
+
+ /*!
+ this method converts 32 bit unsigned int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ uint FromInt(unsigned int i)
+ {
+ return FromUInt(uint(i));
+ }
+
+
+ /*!
+ this method converts 32 bit signed int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ uint FromInt(signed int i)
+ {
+ return FromInt(sint(i));
+ }
+
+
+ /*!
+ this operator converts 32 bit unsigned int type to this class
+ ***this operator is created only on a 64bit platform***
+ */
+ UInt<value_size> & operator=(unsigned int i)
+ {
+ FromUInt(i);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting 32 bit unsigned int to this class
+ ***this constructor is created only on a 64bit platform***
+ */
+ UInt(unsigned int i)
+ {
+ FromUInt(i);
+ }
+
+
+ /*!
+ an operator for converting 32 bit signed int to this class
+ ***this constructor is created only on a 64bit platform***
+ */
+ UInt<value_size> & operator=(signed int i)
+ {
+ FromInt(i);
+
+ return *this;
+ }
+
+
+ /*!
+ a constructor for converting 32 bit signed int to this class
+ ***this constructor is created only on a 64bit platform***
+ */
+ UInt(signed int i)
+ {
+ FromInt(i);
+ }
+
+
+#endif
+
+
+
+
+
+ /*!
+ a constructor for converting a string to this class (with the base=10)
+ */
+ UInt(const char * s)
+ {
+ FromString(s);
+ }
+
+
+ /*!
+ a constructor for converting a string to this class (with the base=10)
+ */
+ UInt(const std::string & s)
+ {
+ FromString( s.c_str() );
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ a constructor for converting a string to this class (with the base=10)
+ */
+ UInt(const wchar_t * s)
+ {
+ FromString(s);
+ }
+
+
+ /*!
+ a constructor for converting a string to this class (with the base=10)
+ */
+ UInt(const std::wstring & s)
+ {
+ FromString( s.c_str() );
+ }
+
+#endif
+
+
+
+
+ /*!
+ a default constructor
+
+ we don't clear the table
+ */
+ UInt()
+ {
+ // when macro TTMATH_DEBUG_LOG is defined
+ // we set special values to the table
+ // in order to be everywhere the same value of the UInt object
+ // without this it would be difficult to analyse the log file
+ #ifdef TTMATH_DEBUG_LOG
+ #ifdef TTMATH_PLATFORM32
+ for(uint i=0 ; i<value_size ; ++i)
+ table[i] = 0xc1c1c1c1;
+ #else
+ for(uint i=0 ; i<value_size ; ++i)
+ table[i] = 0xc1c1c1c1c1c1c1c1;
+ #endif
+ #endif
+ }
+
+
+ /*!
+ a copy constructor
+ */
+ UInt(const UInt<value_size> & u)
+ {
+ for(uint i=0 ; i<value_size ; ++i)
+ table[i] = u.table[i];
+
+ TTMATH_LOG("UInt::UInt(UInt<>)")
+ }
+
+
+
+ /*!
+ a template for producting constructors for copying from another types
+ */
+ template<uint argument_size>
+ UInt(const UInt<argument_size> & u)
+ {
+ // look that 'size' we still set as 'value_size' and not as u.value_size
+ FromUInt(u);
+ }
+
+
+
+
+ /*!
+ a destructor
+ */
+ ~UInt()
+ {
+ }
+
+
+ /*!
+ this method returns the lowest value from table
+
+ we must be sure when we using this method whether the value
+ will hold in an uint type or not (the rest value from the table must be zero)
+ */
+ uint ToUInt() const
+ {
+ return table[0];
+ }
+
+
+ /*!
+ this method converts the value to uint type
+ can return a carry if the value is too long to store it in uint type
+ */
+ uint ToUInt(uint & result) const
+ {
+ result = table[0];
+
+ for(uint i=1 ; i<value_size ; ++i)
+ if( table[i] != 0 )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts the value to uint type
+ can return a carry if the value is too long to store it in uint type
+ */
+ uint ToInt(uint & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts the value to sint type (signed integer)
+ can return a carry if the value is too long to store it in sint type
+ */
+ uint ToInt(sint & result) const
+ {
+ result = sint(table[0]);
+
+ if( (result & TTMATH_UINT_HIGHEST_BIT) != 0 )
+ return 1;
+
+ for(uint i=1 ; i<value_size ; ++i)
+ if( table[i] != 0 )
+ return 1;
+
+ return 0;
+ }
+
+
+#ifdef TTMATH_PLATFORM32
+
+ /*!
+ this method converts the value to ulint type (64 bit unsigned integer)
+ can return a carry if the value is too long to store it in ulint type
+ *** this method is created only on a 32 bit platform ***
+ */
+ uint ToUInt(ulint & result) const
+ {
+ if( value_size == 1 )
+ {
+ result = table[0];
+ }
+ else
+ {
+ uint low = table[0];
+ uint high = table[1];
+
+ result = low;
+ result |= (ulint(high) << TTMATH_BITS_PER_UINT);
+
+ for(uint i=2 ; i<value_size ; ++i)
+ if( table[i] != 0 )
+ return 1;
+ }
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts the value to ulint type (64 bit unsigned integer)
+ can return a carry if the value is too long to store it in ulint type
+ *** this method is created only on a 32 bit platform ***
+ */
+ uint ToInt(ulint & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts the value to slint type (64 bit signed integer)
+ can return a carry if the value is too long to store it in slint type
+ *** this method is created only on a 32 bit platform ***
+ */
+ uint ToInt(slint & result) const
+ {
+ ulint temp;
+
+ uint c = ToUInt(temp);
+ result = slint(temp);
+
+ if( c || result < 0 )
+ return 1;
+
+ return 0;
+ }
+
+#endif
+
+
+
+#ifdef TTMATH_PLATFORM64
+
+ /*!
+ this method converts the value to a 32 unsigned integer
+ can return a carry if the value is too long to store it in this type
+ *** this method is created only on a 64 bit platform ***
+ */
+ uint ToUInt(unsigned int & result) const
+ {
+ result = (unsigned int)table[0];
+
+ if( (table[0] >> 32) != 0 )
+ return 1;
+
+ for(uint i=1 ; i<value_size ; ++i)
+ if( table[i] != 0 )
+ return 1;
+
+ return 0;
+ }
+
+
+ /*!
+ this method converts the value to a 32 unsigned integer
+ can return a carry if the value is too long to store it in this type
+ *** this method is created only on a 64 bit platform ***
+ */
+ uint ToInt(unsigned int & result) const
+ {
+ return ToUInt(result);
+ }
+
+
+ /*!
+ this method converts the value to a 32 signed integer
+ can return a carry if the value is too long to store it in this type
+ *** this method is created only on a 64 bit platform ***
+ */
+ uint ToInt(int & result) const
+ {
+ unsigned int temp;
+
+ uint c = ToUInt(temp);
+ result = int(temp);
+
+ if( c || result < 0 )
+ return 1;
+
+ return 0;
+ }
+
+
+#endif
+
+
+
+
+protected:
+
+ /*!
+ an auxiliary method for converting into the string
+ it returns the log (with the base 2) from x
+ where x is in <2;16>
+ */
+ double ToStringLog2(uint x) const
+ {
+ static double log_tab[] = {
+ 1.000000000000000000,
+ 0.630929753571457437,
+ 0.500000000000000000,
+ 0.430676558073393050,
+ 0.386852807234541586,
+ 0.356207187108022176,
+ 0.333333333333333333,
+ 0.315464876785728718,
+ 0.301029995663981195,
+ 0.289064826317887859,
+ 0.278942945651129843,
+ 0.270238154427319741,
+ 0.262649535037193547,
+ 0.255958024809815489,
+ 0.250000000000000000
+ };
+
+ if( x<2 || x>16 )
+ return 0;
+
+ return log_tab[x-2];
+ }
+
+
+ /*!
+ an auxiliary method for converting to a string
+ it's used from Int::ToString() too (negative is set true then)
+ */
+ template<class string_type>
+ void ToStringBase(string_type & result, uint b = 10, bool negative = false) const
+ {
+ UInt<value_size> temp(*this);
+ uint rest, table_id, index, digits;
+ double digits_d;
+ char character;
+
+ result.clear();
+
+ if( b<2 || b>16 )
+ return;
+
+ if( !FindLeadingBit(table_id, index) )
+ {
+ result = '0';
+ return;
+ }
+
+ if( negative )
+ result = '-';
+
+ digits_d = table_id; // for not making an overflow in uint type
+ digits_d *= TTMATH_BITS_PER_UINT;
+ digits_d += index + 1;
+ digits_d *= ToStringLog2(b);
+ digits = static_cast<uint>(digits_d) + 3; // plus some epsilon
+
+ if( result.capacity() < digits )
+ result.reserve(digits);
+
+ do
+ {
+ temp.DivInt(b, &rest);
+ character = static_cast<char>(Misc::DigitToChar(rest));
+ result.insert(result.end(), character);
+ }
+ while( !temp.IsZero() );
+
+ size_t i1 = negative ? 1 : 0; // the first is a hyphen (when negative is true)
+ size_t i2 = result.size() - 1;
+
+ for( ; i1 < i2 ; ++i1, --i2 )
+ {
+ char tempc = static_cast<char>(result[i1]);
+ result[i1] = result[i2];
+ result[i2] = tempc;
+ }
+ }
+
+
+
+public:
+
+ /*!
+ this method converts the value to a string with a base equal 'b'
+ */
+ void ToString(std::string & result, uint b = 10) const
+ {
+ return ToStringBase(result, b);
+ }
+
+
+ std::string ToString(uint b = 10) const
+ {
+ std::string result;
+ ToStringBase(result, b);
+
+ return result;
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ void ToString(std::wstring & result, uint b = 10) const
+ {
+ return ToStringBase(result, b);
+ }
+
+ std::wstring ToWString(uint b = 10) const
+ {
+ std::wstring result;
+ ToStringBase(result, b);
+
+ return result;
+ }
+
+#endif
+
+
+
+private:
+
+ /*!
+ an auxiliary method for converting from a string
+ */
+ template<class char_type>
+ uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
+ {
+ UInt<value_size> base( b );
+ UInt<value_size> temp;
+ sint z;
+ uint c = 0;
+
+ SetZero();
+ temp.SetZero();
+ Misc::SkipWhiteCharacters(s);
+
+ if( after_source )
+ *after_source = s;
+
+ if( value_read )
+ *value_read = false;
+
+ if( b<2 || b>16 )
+ return 1;
+
+
+ for( ; (z=Misc::CharToDigit(*s, b)) != -1 ; ++s)
+ {
+ if( value_read )
+ *value_read = true;
+
+ if( c == 0 )
+ {
+ temp.table[0] = z;
+
+ c += Mul(base);
+ c += Add(temp);
+ }
+ }
+
+ if( after_source )
+ *after_source = s;
+
+ TTMATH_LOGC("UInt::FromString", c)
+
+ return (c==0)? 0 : 1;
+ }
+
+
+public:
+
+
+ /*!
+ this method converts a string into its value
+ it returns carry=1 if the value will be too big or an incorrect base 'b' is given
+
+ string is ended with a non-digit value, for example:
+ "12" will be translated to 12
+ as well as:
+ "12foo" will be translated to 12 too
+
+ existing first white characters will be ommited
+
+ if the value from s is too large the rest digits will be skipped
+
+ after_source (if exists) is pointing at the end of the parsed string
+
+ value_read (if exists) tells whether something has actually been read (at least one digit)
+ */
+ uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
+ {
+ return FromStringBase(s, b, after_source, value_read);
+ }
+
+
+ /*!
+ this method converts a string into its value
+
+ (it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
+ */
+ uint FromString(const std::string & s, uint b = 10)
+ {
+ return FromString( s.c_str(), b );
+ }
+
+
+ /*!
+ this operator converts a string into its value (with base = 10)
+ */
+ UInt<value_size> & operator=(const char * s)
+ {
+ FromString(s);
+
+ return *this;
+ }
+
+
+ /*!
+ this operator converts a string into its value (with base = 10)
+ */
+ UInt<value_size> & operator=(const std::string & s)
+ {
+ FromString( s.c_str() );
+
+ return *this;
+ }
+
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ this method converts a string into its value
+ */
+ uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+ {
+ return FromStringBase(s, b, after_source, value_read);
+ }
+
+
+ /*!
+ this method converts a string into its value
+
+ (it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
+ */
+ uint FromString(const std::wstring & s, uint b = 10)
+ {
+ return FromString( s.c_str(), b );
+ }
+
+
+ /*!
+ this operator converts a string into its value (with base = 10)
+ */
+ UInt<value_size> & operator=(const wchar_t * s)
+ {
+ FromString(s);
+
+ return *this;
+ }
+
+
+ /*!
+ this operator converts a string into its value (with base = 10)
+ */
+ UInt<value_size> & operator=(const std::wstring & s)
+ {
+ FromString( s.c_str() );
+
+ return *this;
+ }
+
+#endif
+
+
+ /*!
+ *
+ * methods for comparing
+ *
+ */
+
+
+ /*!
+ this method returns true if 'this' is smaller than 'l'
+
+ 'index' is an index of the first word from will be the comparison performed
+ (note: we start the comparison from back - from the last word, when index is -1 /default/
+ it is automatically set into the last word)
+ I introduced it for some kind of optimization made in the second division algorithm (Div2)
+ */
+ bool CmpSmaller(const UInt<value_size> & l, sint index = -1) const
+ {
+ sint i;
+
+ if( index==-1 || index>=sint(value_size) )
+ i = value_size - 1;
+ else
+ i = index;
+
+
+ for( ; i>=0 ; --i)
+ {
+ if( table[i] != l.table[i] )
+ return table[i] < l.table[i];
+ }
+
+ // they're equal
+ return false;
+ }
+
+
+
+ /*!
+ this method returns true if 'this' is bigger than 'l'
+
+ 'index' is an index of the first word from will be the comparison performed
+ (note: we start the comparison from back - from the last word, when index is -1 /default/
+ it is automatically set into the last word)
+
+ I introduced it for some kind of optimization made in the second division algorithm (Div2)
+ */
+ bool CmpBigger(const UInt<value_size> & l, sint index = -1) const
+ {
+ sint i;
+
+ if( index==-1 || index>=sint(value_size) )
+ i = value_size - 1;
+ else
+ i = index;
+
+
+ for( ; i>=0 ; --i)
+ {
+ if( table[i] != l.table[i] )
+ return table[i] > l.table[i];
+ }
+
+ // they're equal
+ return false;
+ }
+
+
+ /*!
+ this method returns true if 'this' is equal 'l'
+
+ 'index' is an index of the first word from will be the comparison performed
+ (note: we start the comparison from back - from the last word, when index is -1 /default/
+ it is automatically set into the last word)
+ */
+ bool CmpEqual(const UInt<value_size> & l, sint index = -1) const
+ {
+ sint i;
+
+ if( index==-1 || index>=sint(value_size) )
+ i = value_size - 1;
+ else
+ i = index;
+
+
+ for( ; i>=0 ; --i)
+ if( table[i] != l.table[i] )
+ return false;
+
+ return true;
+ }
+
+
+
+ /*!
+ this method returns true if 'this' is smaller than or equal 'l'
+
+ 'index' is an index of the first word from will be the comparison performed
+ (note: we start the comparison from back - from the last word, when index is -1 /default/
+ it is automatically set into the last word)
+ */
+ bool CmpSmallerEqual(const UInt<value_size> & l, sint index=-1) const
+ {
+ sint i;
+
+ if( index==-1 || index>=sint(value_size) )
+ i = value_size - 1;
+ else
+ i = index;
+
+
+ for( ; i>=0 ; --i)
+ {
+ if( table[i] != l.table[i] )
+ return table[i] < l.table[i];
+ }
+
+ // they're equal
+ return true;
+ }
+
+
+
+ /*!
+ this method returns true if 'this' is bigger than or equal 'l'
+
+ 'index' is an index of the first word from will be the comparison performed
+ (note: we start the comparison from back - from the last word, when index is -1 /default/
+ it is automatically set into the last word)
+ */
+ bool CmpBiggerEqual(const UInt<value_size> & l, sint index=-1) const
+ {
+ sint i;
+
+ if( index==-1 || index>=sint(value_size) )
+ i = value_size - 1;
+ else
+ i = index;
+
+
+ for( ; i>=0 ; --i)
+ {
+ if( table[i] != l.table[i] )
+ return table[i] > l.table[i];
+ }
+
+ // they're equal
+ return true;
+ }
+
+
+ /*
+ operators for comparising
+ */
+
+ bool operator<(const UInt<value_size> & l) const
+ {
+ return CmpSmaller(l);
+ }
+
+
+ bool operator>(const UInt<value_size> & l) const
+ {
+ return CmpBigger(l);
+ }
+
+
+ bool operator==(const UInt<value_size> & l) const
+ {
+ return CmpEqual(l);
+ }
+
+
+ bool operator!=(const UInt<value_size> & l) const
+ {
+ return !operator==(l);
+ }
+
+
+ bool operator<=(const UInt<value_size> & l) const
+ {
+ return CmpSmallerEqual(l);
+ }
+
+ bool operator>=(const UInt<value_size> & l) const
+ {
+ return CmpBiggerEqual(l);
+ }
+
+
+ /*!
+ *
+ * standard mathematical operators
+ *
+ */
+
+ UInt<value_size> operator-(const UInt<value_size> & p2) const
+ {
+ UInt<value_size> temp(*this);
+
+ temp.Sub(p2);
+
+ return temp;
+ }
+
+ UInt<value_size> & operator-=(const UInt<value_size> & p2)
+ {
+ Sub(p2);
+
+ return *this;
+ }
+
+ UInt<value_size> operator+(const UInt<value_size> & p2) const
+ {
+ UInt<value_size> temp(*this);
+
+ temp.Add(p2);
+
+ return temp;
+ }
+
+ UInt<value_size> & operator+=(const UInt<value_size> & p2)
+ {
+ Add(p2);
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator*(const UInt<value_size> & p2) const
+ {
+ UInt<value_size> temp(*this);
+
+ temp.Mul(p2);
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator*=(const UInt<value_size> & p2)
+ {
+ Mul(p2);
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator/(const UInt<value_size> & p2) const
+ {
+ UInt<value_size> temp(*this);
+
+ temp.Div(p2);
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator/=(const UInt<value_size> & p2)
+ {
+ Div(p2);
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator%(const UInt<value_size> & p2) const
+ {
+ UInt<value_size> temp(*this);
+ UInt<value_size> remainder;
+
+ temp.Div( p2, remainder );
+
+ return remainder;
+ }
+
+
+ UInt<value_size> & operator%=(const UInt<value_size> & p2)
+ {
+ UInt<value_size> remainder;
+
+ Div( p2, remainder );
+ operator=(remainder);
+
+ return *this;
+ }
+
+
+ /*!
+ Prefix operator e.g ++variable
+ */
+ UInt<value_size> & operator++()
+ {
+ AddOne();
+
+ return *this;
+ }
+
+
+ /*!
+ Postfix operator e.g variable++
+ */
+ UInt<value_size> operator++(int)
+ {
+ UInt<value_size> temp( *this );
+
+ AddOne();
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator--()
+ {
+ SubOne();
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator--(int)
+ {
+ UInt<value_size> temp( *this );
+
+ SubOne();
+
+ return temp;
+ }
+
+
+
+ /*!
+ *
+ * bitwise operators
+ *
+ */
+
+ UInt<value_size> operator~() const
+ {
+ UInt<value_size> temp( *this );
+
+ temp.BitNot();
+
+ return temp;
+ }
+
+
+ UInt<value_size> operator&(const UInt<value_size> & p2) const
+ {
+ UInt<value_size> temp( *this );
+
+ temp.BitAnd(p2);
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator&=(const UInt<value_size> & p2)
+ {
+ BitAnd(p2);
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator|(const UInt<value_size> & p2) const
+ {
+ UInt<value_size> temp( *this );
+
+ temp.BitOr(p2);
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator|=(const UInt<value_size> & p2)
+ {
+ BitOr(p2);
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator^(const UInt<value_size> & p2) const
+ {
+ UInt<value_size> temp( *this );
+
+ temp.BitXor(p2);
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator^=(const UInt<value_size> & p2)
+ {
+ BitXor(p2);
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator>>(int move) const
+ {
+ UInt<value_size> temp( *this );
+
+ temp.Rcr(move);
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator>>=(int move)
+ {
+ Rcr(move);
+
+ return *this;
+ }
+
+
+ UInt<value_size> operator<<(int move) const
+ {
+ UInt<value_size> temp( *this );
+
+ temp.Rcl(move);
+
+ return temp;
+ }
+
+
+ UInt<value_size> & operator<<=(int move)
+ {
+ Rcl(move);
+
+ return *this;
+ }
+
+
+ /*!
+ *
+ * input/output operators for standard streams
+ *
+ * (they are very simple, in the future they should be changed)
+ *
+ */
+
+
+private:
+
+
+ /*!
+ an auxiliary method for outputing to standard streams
+ */
+ template<class ostream_type, class string_type>
+ static ostream_type & OutputToStream(ostream_type & s, const UInt<value_size> & l)
+ {
+ string_type ss;
+
+ l.ToString(ss);
+ s << ss;
+
+ return s;
+ }
+
+
+public:
+
+
+ /*!
+ output to standard streams
+ */
+ friend std::ostream & operator<<(std::ostream & s, const UInt<value_size> & l)
+ {
+ return OutputToStream<std::ostream, std::string>(s, l);
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ output to standard streams
+ */
+ friend std::wostream & operator<<(std::wostream & s, const UInt<value_size> & l)
+ {
+ return OutputToStream<std::wostream, std::wstring>(s, l);
+ }
+
+#endif
+
+
+
+private:
+
+ /*!
+ an auxiliary method for reading from standard streams
+ */
+ template<class istream_type, class string_type, class char_type>
+ static istream_type & InputFromStream(istream_type & s, UInt<value_size> & l)
+ {
+ string_type ss;
+
+ // char or wchar_t for operator>>
+ char_type z;
+
+ // operator>> omits white characters if they're set for ommiting
+ s >> z;
+
+ // we're reading only digits (base=10)
+ while( s.good() && Misc::CharToDigit(z, 10)>=0 )
+ {
+ ss += z;
+ z = static_cast<char_type>(s.get());
+ }
+
+ // we're leaving the last read character
+ // (it's not belonging to the value)
+ s.unget();
+
+ l.FromString(ss);
+
+ return s;
+ }
+
+public:
+
+
+ /*!
+ input from standard streams
+ */
+ friend std::istream & operator>>(std::istream & s, UInt<value_size> & l)
+ {
+ return InputFromStream<std::istream, std::string, char>(s, l);
+ }
+
+
+#ifndef TTMATH_DONT_USE_WCHAR
+
+ /*!
+ input from standard streams
+ */
+ friend std::wistream & operator>>(std::wistream & s, UInt<value_size> & l)
+ {
+ return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
+ }
+
+#endif
+
+
+ /*
+ following methods are defined in:
+ ttmathuint_x86.h
+ ttmathuint_x86_64.h
+ ttmathuint_noasm.h
+ */
+
+#ifdef TTMATH_NOASM
+ static uint AddTwoWords(uint a, uint b, uint carry, uint * result);
+ static uint SubTwoWords(uint a, uint b, uint carry, uint * result);
+
+#ifdef TTMATH_PLATFORM64
+
+ union uint_
+ {
+ struct
+ {
+ unsigned int low; // 32 bit
+ unsigned int high; // 32 bit
+ } u_;
+
+ uint u; // 64 bit
+ };
+
+
+ static void DivTwoWords2(uint a,uint b, uint c, uint * r, uint * rest);
+ static uint DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_);
+ static uint DivTwoWordsUnnormalize(uint u, uint d);
+ static unsigned int DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_);
+ static void MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_);
+
+#endif // TTMATH_PLATFORM64
+#endif // TTMATH_NOASM
+
+
+private:
+ uint Rcl2_one(uint c);
+ uint Rcr2_one(uint c);
+ uint Rcl2(uint bits, uint c);
+ uint Rcr2(uint bits, uint c);
+
+public:
+ static const char * LibTypeStr();
+ static LibTypeCode LibType();
+ uint Add(const UInt<value_size> & ss2, uint c=0);
+ uint AddInt(uint value, uint index = 0);
+ uint AddTwoInts(uint x2, uint x1, uint index);
+ static uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
+ uint Sub(const UInt<value_size> & ss2, uint c=0);
+ uint SubInt(uint value, uint index = 0);
+ static uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
+ static sint FindLeadingBitInWord(uint x);
+ static sint FindLowestBitInWord(uint x);
+ static uint SetBitInWord(uint & value, uint bit);
+ static void MulTwoWords(uint a, uint b, uint * result_high, uint * result_low);
+ static void DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest);
+
+};
+
+
+
+/*!
+ this specialization is needed in order to not confused the compiler "error: ISO C++ forbids zero-size array"
+ when compiling Mul3Big2() method
+*/
+template<>
+class UInt<0>
+{
+public:
+ uint table[1];
+
+ void Mul2Big(const UInt<0> &, UInt<0> &) { TTMATH_ASSERT(false) };
+ void SetZero() { TTMATH_ASSERT(false) };
+ uint AddTwoInts(uint, uint, uint) { TTMATH_ASSERT(false) return 0; };
+};
+
+
+} //namespace
+
+
+#include "ttmathuint_x86.h"
+#include "ttmathuint_x86_64.h"
+#include "ttmathuint_noasm.h"
+
+#endif
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h
new file mode 100644
index 0000000..07c73fc
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h
@@ -0,0 +1,1017 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef headerfilettmathuint_noasm
+#define headerfilettmathuint_noasm
+
+
+#ifdef TTMATH_NOASM
+
+/*!
+ \file ttmathuint_noasm.h
+ \brief template class UInt<uint> with methods without any assembler code
+
+ this file is included at the end of ttmathuint.h
+*/
+
+
+namespace ttmath
+{
+
+ /*!
+ returning the string represents the currect type of the library
+ we have following types:
+ asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
+ asm_gcc_32 - with asm code designed for GCC (32 bits)
+ asm_vc_64 - with asm for VC (64 bit)
+ asm_gcc_64 - with asm for GCC (64 bit)
+ no_asm_32 - pure C++ version (32 bit) - without any asm code
+ no_asm_64 - pure C++ version (64 bit) - without any asm code
+ */
+ template<uint value_size>
+ const char * UInt<value_size>::LibTypeStr()
+ {
+ #ifdef TTMATH_PLATFORM32
+ static const char info[] = "no_asm_32";
+ #endif
+
+ #ifdef TTMATH_PLATFORM64
+ static const char info[] = "no_asm_64";
+ #endif
+
+ return info;
+ }
+
+
+ /*!
+ returning the currect type of the library
+ */
+ template<uint value_size>
+ LibTypeCode UInt<value_size>::LibType()
+ {
+ #ifdef TTMATH_PLATFORM32
+ LibTypeCode info = no_asm_32;
+ #endif
+
+ #ifdef TTMATH_PLATFORM64
+ LibTypeCode info = no_asm_64;
+ #endif
+
+ return info;
+ }
+
+
+ /*!
+ this method adds two words together
+ returns carry
+
+ this method is created only when TTMATH_NOASM macro is defined
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result)
+ {
+ uint temp;
+
+ if( carry == 0 )
+ {
+ temp = a + b;
+
+ if( temp < a )
+ carry = 1;
+ }
+ else
+ {
+ carry = 1;
+ temp = a + b + carry;
+
+ if( temp > a ) // !(temp<=a)
+ carry = 0;
+ }
+
+ *result = temp;
+
+ return carry;
+ }
+
+
+
+ /*!
+ this method adding ss2 to the this and adding carry if it's defined
+ (this = this + ss2 + c)
+
+ c must be zero or one (might be a bigger value than 1)
+ function returns carry (1) (if it was)
+ */
+
+ template<uint value_size>
+ uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
+ {
+ uint i;
+
+ for(i=0 ; i<value_size ; ++i)
+ c = AddTwoWords(table[i], ss2.table[i], c, &table[i]);
+
+ TTMATH_LOGC("UInt::Add", c)
+
+ return c;
+ }
+
+
+ /*!
+ this method adds one word (at a specific position)
+ and returns a carry (if it was)
+
+ if we've got (value_size=3):
+ table[0] = 10;
+ table[1] = 30;
+ table[2] = 5;
+ and we call:
+ AddInt(2,1)
+ then it'll be:
+ table[0] = 10;
+ table[1] = 30 + 2;
+ table[2] = 5;
+
+ of course if there was a carry from table[2] it would be returned
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddInt(uint value, uint index)
+ {
+ uint i, c;
+
+ TTMATH_ASSERT( index < value_size )
+
+
+ c = AddTwoWords(table[index], value, 0, &table[index]);
+
+ for(i=index+1 ; i<value_size && c ; ++i)
+ c = AddTwoWords(table[i], 0, c, &table[i]);
+
+ TTMATH_LOGC("UInt::AddInt", c)
+
+ return c;
+ }
+
+
+
+
+
+ /*!
+ this method adds only two unsigned words to the existing value
+ and these words begin on the 'index' position
+ (it's used in the multiplication algorithm 2)
+
+ index should be equal or smaller than value_size-2 (index <= value_size-2)
+ x1 - lower word, x2 - higher word
+
+ for example if we've got value_size equal 4 and:
+ table[0] = 3
+ table[1] = 4
+ table[2] = 5
+ table[3] = 6
+ then let
+ x1 = 10
+ x2 = 20
+ and
+ index = 1
+
+ the result of this method will be:
+ table[0] = 3
+ table[1] = 4 + x1 = 14
+ table[2] = 5 + x2 = 25
+ table[3] = 6
+
+ and no carry at the end of table[3]
+
+ (of course if there was a carry in table[2](5+20) then
+ this carry would be passed to the table[3] etc.)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
+ {
+ uint i, c;
+
+ TTMATH_ASSERT( index < value_size - 1 )
+
+
+ c = AddTwoWords(table[index], x1, 0, &table[index]);
+ c = AddTwoWords(table[index+1], x2, c, &table[index+1]);
+
+ for(i=index+2 ; i<value_size && c ; ++i)
+ c = AddTwoWords(table[i], 0, c, &table[i]);
+
+ TTMATH_LOGC("UInt::AddTwoInts", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this static method addes one vector to the other
+ 'ss1' is larger in size or equal to 'ss2'
+
+ ss1 points to the first (larger) vector
+ ss2 points to the second vector
+ ss1_size - size of the ss1 (and size of the result too)
+ ss2_size - size of the ss2
+ result - is the result vector (which has size the same as ss1: ss1_size)
+
+ Example: ss1_size is 5, ss2_size is 3
+ ss1: ss2: result (output):
+ 5 1 5+1
+ 4 3 4+3
+ 2 7 2+7
+ 6 6
+ 9 9
+ of course the carry is propagated and will be returned from the last item
+ (this method is used by the Karatsuba multiplication algorithm)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+ {
+ uint i, c = 0;
+
+ TTMATH_ASSERT( ss1_size >= ss2_size )
+
+ for(i=0 ; i<ss2_size ; ++i)
+ c = AddTwoWords(ss1[i], ss2[i], c, &result[i]);
+
+ for( ; i<ss1_size ; ++i)
+ c = AddTwoWords(ss1[i], 0, c, &result[i]);
+
+ TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
+
+ return c;
+ }
+
+
+
+
+ /*!
+ this method subtractes one word from the other
+ returns carry
+
+ this method is created only when TTMATH_NOASM macro is defined
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result)
+ {
+ if( carry == 0 )
+ {
+ *result = a - b;
+
+ if( a < b )
+ carry = 1;
+ }
+ else
+ {
+ carry = 1;
+ *result = a - b - carry;
+
+ if( a > b ) // !(a <= b )
+ carry = 0;
+ }
+
+ return carry;
+ }
+
+
+
+
+ /*!
+ this method's subtracting ss2 from the 'this' and subtracting
+ carry if it has been defined
+ (this = this - ss2 - c)
+
+ c must be zero or one (might be a bigger value than 1)
+ function returns carry (1) (if it was)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
+ {
+ uint i;
+
+ for(i=0 ; i<value_size ; ++i)
+ c = SubTwoWords(table[i], ss2.table[i], c, &table[i]);
+
+ TTMATH_LOGC("UInt::Sub", c)
+
+ return c;
+ }
+
+
+
+
+ /*!
+ this method subtracts one word (at a specific position)
+ and returns a carry (if it was)
+
+ if we've got (value_size=3):
+ table[0] = 10;
+ table[1] = 30;
+ table[2] = 5;
+ and we call:
+ SubInt(2,1)
+ then it'll be:
+ table[0] = 10;
+ table[1] = 30 - 2;
+ table[2] = 5;
+
+ of course if there was a carry from table[2] it would be returned
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SubInt(uint value, uint index)
+ {
+ uint i, c;
+
+ TTMATH_ASSERT( index < value_size )
+
+
+ c = SubTwoWords(table[index], value, 0, &table[index]);
+
+ for(i=index+1 ; i<value_size && c ; ++i)
+ c = SubTwoWords(table[i], 0, c, &table[i]);
+
+ TTMATH_LOGC("UInt::SubInt", c)
+
+ return c;
+ }
+
+
+ /*!
+ this static method subtractes one vector from the other
+ 'ss1' is larger in size or equal to 'ss2'
+
+ ss1 points to the first (larger) vector
+ ss2 points to the second vector
+ ss1_size - size of the ss1 (and size of the result too)
+ ss2_size - size of the ss2
+ result - is the result vector (which has size the same as ss1: ss1_size)
+
+ Example: ss1_size is 5, ss2_size is 3
+ ss1: ss2: result (output):
+ 5 1 5-1
+ 4 3 4-3
+ 2 7 2-7
+ 6 6-1 (the borrow from previous item)
+ 9 9
+ return (carry): 0
+ of course the carry (borrow) is propagated and will be returned from the last item
+ (this method is used by the Karatsuba multiplication algorithm)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+ {
+ uint i, c = 0;
+
+ TTMATH_ASSERT( ss1_size >= ss2_size )
+
+ for(i=0 ; i<ss2_size ; ++i)
+ c = SubTwoWords(ss1[i], ss2[i], c, &result[i]);
+
+ for( ; i<ss1_size ; ++i)
+ c = SubTwoWords(ss1[i], 0, c, &result[i]);
+
+ TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
+
+ return c;
+ }
+
+
+
+ /*!
+ this method moves all bits into the left hand side
+ return value <- this <- c
+
+ the lowest *bit* will be held the 'c' and
+ the state of one additional bit (on the left hand side)
+ will be returned
+
+ for example:
+ let this is 001010000
+ after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcl2_one(uint c)
+ {
+ uint i, new_c;
+
+ if( c != 0 )
+ c = 1;
+
+ for(i=0 ; i<value_size ; ++i)
+ {
+ new_c = (table[i] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
+ table[i] = (table[i] << 1) | c;
+ c = new_c;
+ }
+
+ TTMATH_LOGC("UInt::Rcl2_one", c)
+
+ return c;
+ }
+
+
+
+
+
+
+
+ /*!
+ this method moves all bits into the right hand side
+ c -> this -> return value
+
+ the highest *bit* will be held the 'c' and
+ the state of one additional bit (on the right hand side)
+ will be returned
+
+ for example:
+ let this is 000000010
+ after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcr2_one(uint c)
+ {
+ sint i; // signed i
+ uint new_c;
+
+ if( c != 0 )
+ c = TTMATH_UINT_HIGHEST_BIT;
+
+ for(i=sint(value_size)-1 ; i>=0 ; --i)
+ {
+ new_c = (table[i] & 1) ? TTMATH_UINT_HIGHEST_BIT : 0;
+ table[i] = (table[i] >> 1) | c;
+ c = new_c;
+ }
+
+ c = (c != 0)? 1 : 0;
+
+ TTMATH_LOGC("UInt::Rcr2_one", c)
+
+ return c;
+ }
+
+
+
+
+ /*!
+ this method moves all bits into the left hand side
+ return value <- this <- c
+
+ the lowest *bits* will be held the 'c' and
+ the state of one additional bit (on the left hand side)
+ will be returned
+
+ for example:
+ let this is 001010000
+ after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcl2(uint bits, uint c)
+ {
+ TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+ uint move = TTMATH_BITS_PER_UINT - bits;
+ uint i, new_c;
+
+ if( c != 0 )
+ c = TTMATH_UINT_MAX_VALUE >> move;
+
+ for(i=0 ; i<value_size ; ++i)
+ {
+ new_c = table[i] >> move;
+ table[i] = (table[i] << bits) | c;
+ c = new_c;
+ }
+
+ TTMATH_LOGC("UInt::Rcl2", (c & 1))
+
+ return (c & 1);
+ }
+
+
+
+
+ /*!
+ this method moves all bits into the right hand side
+ C -> this -> return value
+
+ the highest *bits* will be held the 'c' and
+ the state of one additional bit (on the right hand side)
+ will be returned
+
+ for example:
+ let this is 000000010
+ after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcr2(uint bits, uint c)
+ {
+ TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+ uint move = TTMATH_BITS_PER_UINT - bits;
+ sint i; // signed
+ uint new_c;
+
+ if( c != 0 )
+ c = TTMATH_UINT_MAX_VALUE << move;
+
+ for(i=value_size-1 ; i>=0 ; --i)
+ {
+ new_c = table[i] << move;
+ table[i] = (table[i] >> bits) | c;
+ c = new_c;
+ }
+
+ c = (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
+
+ TTMATH_LOGC("UInt::Rcr2", c)
+
+ return c;
+ }
+
+
+
+
+ /*!
+ this method returns the number of the highest set bit in x
+ if the 'x' is zero this method returns '-1'
+ */
+ template<uint value_size>
+ sint UInt<value_size>::FindLeadingBitInWord(uint x)
+ {
+ if( x == 0 )
+ return -1;
+
+ uint bit = TTMATH_BITS_PER_UINT - 1;
+
+ while( (x & TTMATH_UINT_HIGHEST_BIT) == 0 )
+ {
+ x = x << 1;
+ --bit;
+ }
+
+ return bit;
+ }
+
+
+
+ /*!
+ this method returns the number of the highest set bit in x
+ if the 'x' is zero this method returns '-1'
+ */
+ template<uint value_size>
+ sint UInt<value_size>::FindLowestBitInWord(uint x)
+ {
+ if( x == 0 )
+ return -1;
+
+ uint bit = 0;
+
+ while( (x & 1) == 0 )
+ {
+ x = x >> 1;
+ ++bit;
+ }
+
+ return bit;
+ }
+
+
+
+ /*!
+ this method sets a special bit in the 'value'
+ and returns the last state of the bit (zero or one)
+
+ bit is from <0,TTMATH_BITS_PER_UINT-1>
+
+ e.g.
+ uint x = 100;
+ uint bit = SetBitInWord(x, 3);
+ now: x = 108 and bit = 0
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
+ {
+ TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
+
+ uint mask = 1;
+
+ if( bit > 0 )
+ mask = mask << bit;
+
+ uint last = value & mask;
+ value = value | mask;
+
+ return (last != 0) ? 1 : 0;
+ }
+
+
+
+
+
+
+ /*!
+ *
+ * Multiplication
+ *
+ *
+ */
+
+
+ /*!
+ multiplication: result_high:result_low = a * b
+ result_high - higher word of the result
+ result_low - lower word of the result
+
+ this methos never returns a carry
+ this method is used in the second version of the multiplication algorithms
+ */
+ template<uint value_size>
+ void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low)
+ {
+ #ifdef TTMATH_PLATFORM32
+
+ /*
+ on 32bit platforms we have defined 'unsigned long long int' type known as 'ulint' in ttmath namespace
+ this type has 64 bits, then we're using only one multiplication: 32bit * 32bit = 64bit
+ */
+
+ union uint_
+ {
+ struct
+ {
+ uint low; // 32 bits
+ uint high; // 32 bits
+ } u_;
+
+ ulint u; // 64 bits
+ } res;
+
+ res.u = ulint(a) * ulint(b); // multiply two 32bit words, the result has 64 bits
+
+ *result_high = res.u_.high;
+ *result_low = res.u_.low;
+
+ #else
+
+ /*
+ 64 bits platforms
+
+ we don't have a native type which has 128 bits
+ then we're splitting 'a' and 'b' to 4 parts (high and low halves)
+ and using 4 multiplications (with additions and carry correctness)
+ */
+
+ uint_ a_;
+ uint_ b_;
+ uint_ res_high1, res_high2;
+ uint_ res_low1, res_low2;
+
+ a_.u = a;
+ b_.u = b;
+
+ /*
+ the multiplication is as follows (schoolbook algorithm with O(n^2) ):
+
+ 32 bits 32 bits
+
+ +--------------------------------+
+ | a_.u_.high | a_.u_.low |
+ +--------------------------------+
+ | b_.u_.high | b_.u_.low |
+ +--------------------------------+--------------------------------+
+ | res_high1.u | res_low1.u |
+ +--------------------------------+--------------------------------+
+ | res_high2.u | res_low2.u |
+ +--------------------------------+--------------------------------+
+
+ 64 bits 64 bits
+ */
+
+
+ uint_ temp;
+
+ res_low1.u = uint(b_.u_.low) * uint(a_.u_.low);
+
+ temp.u = uint(res_low1.u_.high) + uint(b_.u_.low) * uint(a_.u_.high);
+ res_low1.u_.high = temp.u_.low;
+ res_high1.u_.low = temp.u_.high;
+ res_high1.u_.high = 0;
+
+ res_low2.u_.low = 0;
+ temp.u = uint(b_.u_.high) * uint(a_.u_.low);
+ res_low2.u_.high = temp.u_.low;
+
+ res_high2.u = uint(b_.u_.high) * uint(a_.u_.high) + uint(temp.u_.high);
+
+ uint c = AddTwoWords(res_low1.u, res_low2.u, 0, &res_low2.u);
+ AddTwoWords(res_high1.u, res_high2.u, c, &res_high2.u); // there is no carry from here
+
+ *result_high = res_high2.u;
+ *result_low = res_low2.u;
+
+ #endif
+ }
+
+
+
+
+ /*!
+ *
+ * Division
+ *
+ *
+ */
+
+
+ /*!
+ this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
+ r = a:b / c and rest - remainder
+
+ *
+ * WARNING:
+ * the c has to be suitably large for the result being keeped in one word,
+ * if c is equal zero there'll be a hardware interruption (0)
+ * and probably the end of your program
+ *
+ */
+ template<uint value_size>
+ void UInt<value_size>::DivTwoWords(uint a, uint b, uint c, uint * r, uint * rest)
+ {
+ // (a < c ) for the result to be one word
+ TTMATH_ASSERT( c != 0 && a < c )
+
+ #ifdef TTMATH_PLATFORM32
+
+ union
+ {
+ struct
+ {
+ uint low; // 32 bits
+ uint high; // 32 bits
+ } u_;
+
+ ulint u; // 64 bits
+ } ab;
+
+ ab.u_.high = a;
+ ab.u_.low = b;
+
+ *r = uint(ab.u / c);
+ *rest = uint(ab.u % c);
+
+ #else
+
+ uint_ c_;
+ c_.u = c;
+
+
+ if( a == 0 )
+ {
+ *r = b / c;
+ *rest = b % c;
+ }
+ else
+ if( c_.u_.high == 0 )
+ {
+ // higher half of 'c' is zero
+ // then higher half of 'a' is zero too (look at the asserts at the beginning - 'a' is smaller than 'c')
+ uint_ a_, b_, res_, temp1, temp2;
+
+ a_.u = a;
+ b_.u = b;
+
+ temp1.u_.high = a_.u_.low;
+ temp1.u_.low = b_.u_.high;
+
+ res_.u_.high = (unsigned int)(temp1.u / c);
+ temp2.u_.high = (unsigned int)(temp1.u % c);
+ temp2.u_.low = b_.u_.low;
+
+ res_.u_.low = (unsigned int)(temp2.u / c);
+ *rest = temp2.u % c;
+
+ *r = res_.u;
+ }
+ else
+ {
+ return DivTwoWords2(a, b, c, r, rest);
+ }
+
+ #endif
+ }
+
+
+#ifdef TTMATH_PLATFORM64
+
+
+ /*!
+ this method is available only on 64bit platforms
+
+ the same algorithm like the third division algorithm in ttmathuint.h
+ but now with the radix=2^32
+ */
+ template<uint value_size>
+ void UInt<value_size>::DivTwoWords2(uint a, uint b, uint c, uint * r, uint * rest)
+ {
+ // a is not zero
+ // c_.u_.high is not zero
+
+ uint_ a_, b_, c_, u_, q_;
+ unsigned int u3; // 32 bit
+
+ a_.u = a;
+ b_.u = b;
+ c_.u = c;
+
+ // normalizing
+ uint d = DivTwoWordsNormalize(a_, b_, c_);
+
+ // loop from j=1 to j=0
+ // the first step (for j=2) is skipped because our result is only in one word,
+ // (first 'q' were 0 and nothing would be changed)
+ u_.u_.high = a_.u_.high;
+ u_.u_.low = a_.u_.low;
+ u3 = b_.u_.high;
+ q_.u_.high = DivTwoWordsCalculate(u_, u3, c_);
+ MultiplySubtract(u_, u3, q_.u_.high, c_);
+
+ u_.u_.high = u_.u_.low;
+ u_.u_.low = u3;
+ u3 = b_.u_.low;
+ q_.u_.low = DivTwoWordsCalculate(u_, u3, c_);
+ MultiplySubtract(u_, u3, q_.u_.low, c_);
+
+ *r = q_.u;
+
+ // unnormalizing for the remainder
+ u_.u_.high = u_.u_.low;
+ u_.u_.low = u3;
+ *rest = DivTwoWordsUnnormalize(u_.u, d);
+ }
+
+
+
+
+ template<uint value_size>
+ uint UInt<value_size>::DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_)
+ {
+ uint d = 0;
+
+ for( ; (c_.u & TTMATH_UINT_HIGHEST_BIT) == 0 ; ++d )
+ {
+ c_.u = c_.u << 1;
+
+ uint bc = b_.u & TTMATH_UINT_HIGHEST_BIT; // carry from 'b'
+
+ b_.u = b_.u << 1;
+ a_.u = a_.u << 1; // carry bits from 'a' are simply skipped
+
+ if( bc )
+ a_.u = a_.u | 1;
+ }
+
+ return d;
+ }
+
+
+ template<uint value_size>
+ uint UInt<value_size>::DivTwoWordsUnnormalize(uint u, uint d)
+ {
+ if( d == 0 )
+ return u;
+
+ u = u >> d;
+
+ return u;
+ }
+
+
+ template<uint value_size>
+ unsigned int UInt<value_size>::DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_)
+ {
+ bool next_test;
+ uint_ qp_, rp_, temp_;
+
+ qp_.u = u_.u / uint(v_.u_.high);
+ rp_.u = u_.u % uint(v_.u_.high);
+
+ TTMATH_ASSERT( qp_.u_.high==0 || qp_.u_.high==1 )
+
+ do
+ {
+ bool decrease = false;
+
+ if( qp_.u_.high == 1 )
+ decrease = true;
+ else
+ {
+ temp_.u_.high = rp_.u_.low;
+ temp_.u_.low = u3;
+
+ if( qp_.u * uint(v_.u_.low) > temp_.u )
+ decrease = true;
+ }
+
+ next_test = false;
+
+ if( decrease )
+ {
+ --qp_.u;
+ rp_.u += v_.u_.high;
+
+ if( rp_.u_.high == 0 )
+ next_test = true;
+ }
+ }
+ while( next_test );
+
+ return qp_.u_.low;
+ }
+
+
+ template<uint value_size>
+ void UInt<value_size>::MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_)
+ {
+ uint_ temp_;
+
+ uint res_high;
+ uint res_low;
+
+ MulTwoWords(v_.u, q, &res_high, &res_low);
+
+ uint_ sub_res_high_;
+ uint_ sub_res_low_;
+
+ temp_.u_.high = u_.u_.low;
+ temp_.u_.low = u3;
+
+ uint c = SubTwoWords(temp_.u, res_low, 0, &sub_res_low_.u);
+
+ temp_.u_.high = 0;
+ temp_.u_.low = u_.u_.high;
+ c = SubTwoWords(temp_.u, res_high, c, &sub_res_high_.u);
+
+ if( c )
+ {
+ --q;
+
+ c = AddTwoWords(sub_res_low_.u, v_.u, 0, &sub_res_low_.u);
+ AddTwoWords(sub_res_high_.u, 0, c, &sub_res_high_.u);
+ }
+
+ u_.u_.high = sub_res_high_.u_.low;
+ u_.u_.low = sub_res_low_.u_.high;
+ u3 = sub_res_low_.u_.low;
+ }
+
+#endif // #ifdef TTMATH_PLATFORM64
+
+
+
+} //namespace
+
+
+#endif //ifdef TTMATH_NOASM
+#endif
+
+
+
+
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h
new file mode 100644
index 0000000..1dd087f
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h
@@ -0,0 +1,1602 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathuint_x86
+#define headerfilettmathuint_x86
+
+
+#ifndef TTMATH_NOASM
+#ifdef TTMATH_PLATFORM32
+
+
+/*!
+ \file ttmathuint_x86.h
+ \brief template class UInt<uint> with assembler code for 32bit x86 processors
+
+ this file is included at the end of ttmathuint.h
+*/
+
+
+
+/*!
+ \brief a namespace for the TTMath library
+*/
+namespace ttmath
+{
+
+ /*!
+ returning the string represents the currect type of the library
+ we have following types:
+ asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
+ asm_gcc_32 - with asm code designed for GCC (32 bits)
+ asm_vc_64 - with asm for VC (64 bit)
+ asm_gcc_64 - with asm for GCC (64 bit)
+ no_asm_32 - pure C++ version (32 bit) - without any asm code
+ no_asm_64 - pure C++ version (64 bit) - without any asm code
+ */
+ template<uint value_size>
+ const char * UInt<value_size>::LibTypeStr()
+ {
+ #ifndef __GNUC__
+ static const char info[] = "asm_vc_32";
+ #endif
+
+ #ifdef __GNUC__
+ static const char info[] = "asm_gcc_32";
+ #endif
+
+ return info;
+ }
+
+
+ /*!
+ returning the currect type of the library
+ */
+ template<uint value_size>
+ LibTypeCode UInt<value_size>::LibType()
+ {
+ #ifndef __GNUC__
+ LibTypeCode info = asm_vc_32;
+ #endif
+
+ #ifdef __GNUC__
+ LibTypeCode info = asm_gcc_32;
+ #endif
+
+ return info;
+ }
+
+
+
+ /*!
+ *
+ * basic mathematic functions
+ *
+ */
+
+
+ /*!
+ adding ss2 to the this and adding carry if it's defined
+ (this = this + ss2 + c)
+
+ c must be zero or one (might be a bigger value than 1)
+ function returns carry (1) (if it has been)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ uint * p2 = const_cast<uint*>(ss2.table);
+
+ // we don't have to use TTMATH_REFERENCE_ASSERT here
+ // this algorithm doesn't require it
+
+ #ifndef __GNUC__
+
+ // this part might be compiled with for example visual c
+
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+ push esi
+
+ mov ecx,[b]
+
+ mov ebx,[p1]
+ mov esi,[p2]
+
+ xor edx,edx // edx=0
+ mov eax,[c]
+ neg eax // CF=1 if rax!=0 , CF=0 if rax==0
+
+ ttmath_loop:
+ mov eax,[esi+edx*4]
+ adc [ebx+edx*4],eax
+
+ inc edx
+ dec ecx
+ jnz ttmath_loop
+
+ adc ecx, ecx
+ mov [c], ecx
+
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+
+
+
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+ // this part should be compiled with gcc
+
+ __asm__ __volatile__(
+
+ "xorl %%edx, %%edx \n"
+ "negl %%eax \n" // CF=1 if rax!=0 , CF=0 if rax==0
+
+ "1: \n"
+ "movl (%%esi,%%edx,4), %%eax \n"
+ "adcl %%eax, (%%ebx,%%edx,4) \n"
+
+ "incl %%edx \n"
+ "decl %%ecx \n"
+ "jnz 1b \n"
+
+ "adc %%ecx, %%ecx \n"
+
+ : "=c" (c), "=a" (dummy), "=d" (dummy2)
+ : "0" (b), "1" (c), "b" (p1), "S" (p2)
+ : "cc", "memory" );
+ #endif
+
+ TTMATH_LOGC("UInt::Add", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ adding one word (at a specific position)
+ and returning a carry (if it has been)
+
+ e.g.
+
+ if we've got (value_size=3):
+ table[0] = 10;
+ table[1] = 30;
+ table[2] = 5;
+ and we call:
+ AddInt(2,1)
+ then it'll be:
+ table[0] = 10;
+ table[1] = 30 + 2;
+ table[2] = 5;
+
+ of course if there was a carry from table[2] it would be returned
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddInt(uint value, uint index)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ uint c;
+
+ TTMATH_ASSERT( index < value_size )
+
+ #ifndef __GNUC__
+
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+
+ mov ecx, [b]
+ sub ecx, [index]
+
+ mov edx, [index]
+ mov ebx, [p1]
+
+ mov eax, [value]
+
+ ttmath_loop:
+ add [ebx+edx*4], eax
+ jnc ttmath_end
+
+ mov eax, 1
+ inc edx
+ dec ecx
+ jnz ttmath_loop
+
+ ttmath_end:
+ setc al
+ movzx edx, al
+ mov [c], edx
+
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "subl %%edx, %%ecx \n"
+
+ "1: \n"
+ "addl %%eax, (%%ebx,%%edx,4) \n"
+ "jnc 2f \n"
+
+ "movl $1, %%eax \n"
+ "incl %%edx \n"
+ "decl %%ecx \n"
+ "jnz 1b \n"
+
+ "2: \n"
+ "setc %%al \n"
+ "movzx %%al, %%edx \n"
+
+ : "=d" (c), "=a" (dummy), "=c" (dummy2)
+ : "0" (index), "1" (value), "2" (b), "b" (p1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::AddInt", c)
+
+ return c;
+ }
+
+
+
+
+ /*!
+ adding only two unsigned words to the existing value
+ and these words begin on the 'index' position
+ (it's used in the multiplication algorithm 2)
+
+ index should be equal or smaller than value_size-2 (index <= value_size-2)
+ x1 - lower word, x2 - higher word
+
+ for example if we've got value_size equal 4 and:
+ table[0] = 3
+ table[1] = 4
+ table[2] = 5
+ table[3] = 6
+ then let
+ x1 = 10
+ x2 = 20
+ and
+ index = 1
+
+ the result of this method will be:
+ table[0] = 3
+ table[1] = 4 + x1 = 14
+ table[2] = 5 + x2 = 25
+ table[3] = 6
+
+ and no carry at the end of table[3]
+
+ (of course if there was a carry in table[2](5+20) then
+ this carry would be passed to the table[3] etc.)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ uint c;
+
+ TTMATH_ASSERT( index < value_size - 1 )
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+
+ mov ecx, [b]
+ sub ecx, [index]
+
+ mov ebx, [p1]
+ mov edx, [index]
+
+ mov eax, [x1]
+ add [ebx+edx*4], eax
+ inc edx
+ dec ecx
+
+ mov eax, [x2]
+
+ ttmath_loop:
+ adc [ebx+edx*4], eax
+ jnc ttmath_end
+
+ mov eax, 0
+ inc edx
+ dec ecx
+ jnz ttmath_loop
+
+ ttmath_end:
+ setc al
+ movzx edx, al
+ mov [c], edx
+
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "subl %%edx, %%ecx \n"
+
+ "addl %%esi, (%%ebx,%%edx,4) \n"
+ "incl %%edx \n"
+ "decl %%ecx \n"
+
+ "1: \n"
+ "adcl %%eax, (%%ebx,%%edx,4) \n"
+ "jnc 2f \n"
+
+ "mov $0, %%eax \n"
+ "incl %%edx \n"
+ "decl %%ecx \n"
+ "jnz 1b \n"
+
+ "2: \n"
+ "setc %%al \n"
+ "movzx %%al, %%eax \n"
+
+ : "=a" (c), "=c" (dummy), "=d" (dummy2)
+ : "0" (x2), "1" (b), "2" (index), "b" (p1), "S" (x1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::AddTwoInts", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this static method addes one vector to the other
+ 'ss1' is larger in size or equal to 'ss2'
+
+ ss1 points to the first (larger) vector
+ ss2 points to the second vector
+ ss1_size - size of the ss1 (and size of the result too)
+ ss2_size - size of the ss2
+ result - is the result vector (which has size the same as ss1: ss1_size)
+
+ Example: ss1_size is 5, ss2_size is 3
+ ss1: ss2: result (output):
+ 5 1 5+1
+ 4 3 4+3
+ 2 7 2+7
+ 6 6
+ 9 9
+ of course the carry is propagated and will be returned from the last item
+ (this method is used by the Karatsuba multiplication algorithm)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+ {
+ TTMATH_ASSERT( ss1_size >= ss2_size )
+
+ uint rest = ss1_size - ss2_size;
+ uint c;
+
+ #ifndef __GNUC__
+
+ // this part might be compiled with for example visual c
+ __asm
+ {
+ pushad
+
+ mov ecx, [ss2_size]
+ xor edx, edx // edx = 0, cf = 0
+
+ mov esi, [ss1]
+ mov ebx, [ss2]
+ mov edi, [result]
+
+ ttmath_loop:
+ mov eax, [esi+edx*4]
+ adc eax, [ebx+edx*4]
+ mov [edi+edx*4], eax
+
+ inc edx
+ dec ecx
+ jnz ttmath_loop
+
+ adc ecx, ecx // ecx has the cf state
+
+ mov ebx, [rest]
+ or ebx, ebx
+ jz ttmath_end
+
+ xor ebx, ebx // ebx = 0
+ neg ecx // setting cf from ecx
+ mov ecx, [rest] // ecx is != 0
+
+ ttmath_loop2:
+ mov eax, [esi+edx*4]
+ adc eax, ebx
+ mov [edi+edx*4], eax
+
+ inc edx
+ dec ecx
+ jnz ttmath_loop2
+
+ adc ecx, ecx
+
+ ttmath_end:
+ mov [c], ecx
+
+ popad
+ }
+
+ #endif
+
+
+ #ifdef __GNUC__
+
+ // this part should be compiled with gcc
+ uint dummy1, dummy2, dummy3;
+
+ __asm__ __volatile__(
+ "push %%edx \n"
+ "xor %%edx, %%edx \n" // edx = 0, cf = 0
+ "1: \n"
+ "mov (%%esi,%%edx,4), %%eax \n"
+ "adc (%%ebx,%%edx,4), %%eax \n"
+ "mov %%eax, (%%edi,%%edx,4) \n"
+
+ "inc %%edx \n"
+ "dec %%ecx \n"
+ "jnz 1b \n"
+
+ "adc %%ecx, %%ecx \n" // ecx has the cf state
+ "pop %%eax \n" // eax = rest
+
+ "or %%eax, %%eax \n"
+ "jz 3f \n"
+
+ "xor %%ebx, %%ebx \n" // ebx = 0
+ "neg %%ecx \n" // setting cf from ecx
+ "mov %%eax, %%ecx \n" // ecx=rest and is != 0
+ "2: \n"
+ "mov (%%esi, %%edx, 4), %%eax \n"
+ "adc %%ebx, %%eax \n"
+ "mov %%eax, (%%edi, %%edx, 4) \n"
+
+ "inc %%edx \n"
+ "dec %%ecx \n"
+ "jnz 2b \n"
+
+ "adc %%ecx, %%ecx \n"
+ "3: \n"
+
+ : "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3)
+ : "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
+
+ return c;
+ }
+
+
+ /*!
+ subtracting ss2 from the 'this' and subtracting
+ carry if it has been defined
+ (this = this - ss2 - c)
+
+ c must be zero or one (might be a bigger value than 1)
+ function returns carry (1) (if it has been)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ uint * p2 = const_cast<uint*>(ss2.table);
+
+ // we don't have to use TTMATH_REFERENCE_ASSERT here
+ // this algorithm doesn't require it
+
+ #ifndef __GNUC__
+
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+ push esi
+
+ mov ecx,[b]
+
+ mov ebx,[p1]
+ mov esi,[p2]
+
+ xor edx,edx // edx=0
+ mov eax,[c]
+ neg eax // CF=1 if rax!=0 , CF=0 if rax==0
+
+ ttmath_loop:
+ mov eax,[esi+edx*4]
+ sbb [ebx+edx*4],eax
+
+ inc edx
+ dec ecx
+ jnz ttmath_loop
+
+ adc ecx, ecx
+ mov [c], ecx
+
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "xorl %%edx, %%edx \n"
+ "negl %%eax \n" // CF=1 if rax!=0 , CF=0 if rax==0
+
+ "1: \n"
+ "movl (%%esi,%%edx,4), %%eax \n"
+ "sbbl %%eax, (%%ebx,%%edx,4) \n"
+
+ "incl %%edx \n"
+ "decl %%ecx \n"
+ "jnz 1b \n"
+
+ "adc %%ecx, %%ecx \n"
+
+ : "=c" (c), "=a" (dummy), "=d" (dummy2)
+ : "0" (b), "1" (c), "b" (p1), "S" (p2)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Sub", c)
+
+ return c;
+ }
+
+
+
+
+ /*!
+ this method subtracts one word (at a specific position)
+ and returns a carry (if it was)
+
+ e.g.
+
+ if we've got (value_size=3):
+ table[0] = 10;
+ table[1] = 30;
+ table[2] = 5;
+ and we call:
+ SubInt(2,1)
+ then it'll be:
+ table[0] = 10;
+ table[1] = 30 - 2;
+ table[2] = 5;
+
+ of course if there was a carry from table[2] it would be returned
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SubInt(uint value, uint index)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ uint c;
+
+ TTMATH_ASSERT( index < value_size )
+
+ #ifndef __GNUC__
+
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+
+ mov ecx, [b]
+ sub ecx, [index]
+
+ mov edx, [index]
+ mov ebx, [p1]
+
+ mov eax, [value]
+
+ ttmath_loop:
+ sub [ebx+edx*4], eax
+ jnc ttmath_end
+
+ mov eax, 1
+ inc edx
+ dec ecx
+ jnz ttmath_loop
+
+ ttmath_end:
+ setc al
+ movzx edx, al
+ mov [c], edx
+
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "subl %%edx, %%ecx \n"
+
+ "1: \n"
+ "subl %%eax, (%%ebx,%%edx,4) \n"
+ "jnc 2f \n"
+
+ "movl $1, %%eax \n"
+ "incl %%edx \n"
+ "decl %%ecx \n"
+ "jnz 1b \n"
+
+ "2: \n"
+ "setc %%al \n"
+ "movzx %%al, %%edx \n"
+
+ : "=d" (c), "=a" (dummy), "=c" (dummy2)
+ : "0" (index), "1" (value), "2" (b), "b" (p1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::SubInt", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this static method subtractes one vector from the other
+ 'ss1' is larger in size or equal to 'ss2'
+
+ ss1 points to the first (larger) vector
+ ss2 points to the second vector
+ ss1_size - size of the ss1 (and size of the result too)
+ ss2_size - size of the ss2
+ result - is the result vector (which has size the same as ss1: ss1_size)
+
+ Example: ss1_size is 5, ss2_size is 3
+ ss1: ss2: result (output):
+ 5 1 5-1
+ 4 3 4-3
+ 2 7 2-7
+ 6 6-1 (the borrow from previous item)
+ 9 9
+ return (carry): 0
+ of course the carry (borrow) is propagated and will be returned from the last item
+ (this method is used by the Karatsuba multiplication algorithm)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+ {
+ TTMATH_ASSERT( ss1_size >= ss2_size )
+
+ uint rest = ss1_size - ss2_size;
+ uint c;
+
+ #ifndef __GNUC__
+
+ // this part might be compiled with for example visual c
+
+ /*
+ the asm code is nearly the same as in AddVector
+ only two instructions 'adc' are changed to 'sbb'
+ */
+ __asm
+ {
+ pushad
+
+ mov ecx, [ss2_size]
+ xor edx, edx // edx = 0, cf = 0
+
+ mov esi, [ss1]
+ mov ebx, [ss2]
+ mov edi, [result]
+
+ ttmath_loop:
+ mov eax, [esi+edx*4]
+ sbb eax, [ebx+edx*4]
+ mov [edi+edx*4], eax
+
+ inc edx
+ dec ecx
+ jnz ttmath_loop
+
+ adc ecx, ecx // ecx has the cf state
+
+ mov ebx, [rest]
+ or ebx, ebx
+ jz ttmath_end
+
+ xor ebx, ebx // ebx = 0
+ neg ecx // setting cf from ecx
+ mov ecx, [rest] // ecx is != 0
+
+ ttmath_loop2:
+ mov eax, [esi+edx*4]
+ sbb eax, ebx
+ mov [edi+edx*4], eax
+
+ inc edx
+ dec ecx
+ jnz ttmath_loop2
+
+ adc ecx, ecx
+
+ ttmath_end:
+ mov [c], ecx
+
+ popad
+ }
+
+ #endif
+
+
+ #ifdef __GNUC__
+
+ // this part should be compiled with gcc
+ uint dummy1, dummy2, dummy3;
+
+ __asm__ __volatile__(
+ "push %%edx \n"
+ "xor %%edx, %%edx \n" // edx = 0, cf = 0
+ "1: \n"
+ "mov (%%esi,%%edx,4), %%eax \n"
+ "sbb (%%ebx,%%edx,4), %%eax \n"
+ "mov %%eax, (%%edi,%%edx,4) \n"
+
+ "inc %%edx \n"
+ "dec %%ecx \n"
+ "jnz 1b \n"
+
+ "adc %%ecx, %%ecx \n" // ecx has the cf state
+ "pop %%eax \n" // eax = rest
+
+ "or %%eax, %%eax \n"
+ "jz 3f \n"
+
+ "xor %%ebx, %%ebx \n" // ebx = 0
+ "neg %%ecx \n" // setting cf from ecx
+ "mov %%eax, %%ecx \n" // ecx=rest and is != 0
+ "2: \n"
+ "mov (%%esi, %%edx, 4), %%eax \n"
+ "sbb %%ebx, %%eax \n"
+ "mov %%eax, (%%edi, %%edx, 4) \n"
+
+ "inc %%edx \n"
+ "dec %%ecx \n"
+ "jnz 2b \n"
+
+ "adc %%ecx, %%ecx \n"
+ "3: \n"
+
+ : "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3)
+ : "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
+
+ return c;
+ }
+
+
+
+ /*!
+ this method moves all bits into the left hand side
+ return value <- this <- c
+
+ the lowest *bit* will be held the 'c' and
+ the state of one additional bit (on the left hand side)
+ will be returned
+
+ for example:
+ let this is 001010000
+ after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcl2_one(uint c)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push ebx
+ push ecx
+ push edx
+
+ mov ebx, [p1]
+ xor edx, edx
+ mov ecx, [c]
+ neg ecx
+ mov ecx, [b]
+
+ ttmath_loop:
+ rcl dword ptr [ebx+edx*4], 1
+
+ inc edx
+ dec ecx
+ jnz ttmath_loop
+
+ adc ecx, ecx
+ mov [c], ecx
+
+ pop edx
+ pop ecx
+ pop ebx
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "xorl %%edx, %%edx \n" // edx=0
+ "negl %%eax \n" // CF=1 if eax!=0 , CF=0 if eax==0
+
+ "1: \n"
+ "rcll $1, (%%ebx, %%edx, 4) \n"
+
+ "incl %%edx \n"
+ "decl %%ecx \n"
+ "jnz 1b \n"
+
+ "adcl %%ecx, %%ecx \n"
+
+ : "=c" (c), "=a" (dummy), "=d" (dummy2)
+ : "0" (b), "1" (c), "b" (p1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Rcl2_one", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this method moves all bits into the right hand side
+ c -> this -> return value
+
+ the highest *bit* will be held the 'c' and
+ the state of one additional bit (on the right hand side)
+ will be returned
+
+ for example:
+ let this is 000000010
+ after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcr2_one(uint c)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push ebx
+ push ecx
+
+ mov ebx, [p1]
+ mov ecx, [c]
+ neg ecx
+ mov ecx, [b]
+
+ ttmath_loop:
+ rcr dword ptr [ebx+ecx*4-4], 1
+
+ dec ecx
+ jnz ttmath_loop
+
+ adc ecx, ecx
+ mov [c], ecx
+
+ pop ecx
+ pop ebx
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy;
+
+ __asm__ __volatile__(
+
+ "negl %%eax \n" // CF=1 if eax!=0 , CF=0 if eax==0
+
+ "1: \n"
+ "rcrl $1, -4(%%ebx, %%ecx, 4) \n"
+
+ "decl %%ecx \n"
+ "jnz 1b \n"
+
+ "adcl %%ecx, %%ecx \n"
+
+ : "=c" (c), "=a" (dummy)
+ : "0" (b), "1" (c), "b" (p1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Rcr2_one", c)
+
+ return c;
+ }
+
+
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4731)
+//warning C4731: frame pointer register 'ebp' modified by inline assembly code
+#endif
+
+
+
+ /*!
+ this method moves all bits into the left hand side
+ return value <- this <- c
+
+ the lowest *bits* will be held the 'c' and
+ the state of one additional bit (on the left hand side)
+ will be returned
+
+ for example:
+ let this is 001010000
+ after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcl2(uint bits, uint c)
+ {
+ TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+ uint b = value_size;
+ uint * p1 = table;
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+ push esi
+ push edi
+ push ebp
+
+ mov edi, [b]
+
+ mov ecx, 32
+ sub ecx, [bits]
+ mov edx, -1
+ shr edx, cl
+
+ mov ecx, [bits]
+ mov ebx, [p1]
+ mov eax, [c]
+
+ mov ebp, edx // ebp = mask (modified ebp - don't read/write to variables)
+
+ xor edx, edx // edx = 0
+ mov esi, edx
+ or eax, eax
+ cmovnz esi, ebp // if(c) esi=mask else esi=0
+
+ ttmath_loop:
+ rol dword ptr [ebx+edx*4], cl
+
+ mov eax, [ebx+edx*4]
+ and eax, ebp
+ xor [ebx+edx*4], eax // clearing bits
+ or [ebx+edx*4], esi // saving old value
+ mov esi, eax
+
+ inc edx
+ dec edi
+ jnz ttmath_loop
+
+ pop ebp // restoring ebp
+
+ and eax, 1
+ mov [c], eax
+
+ pop edi
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2, dummy3;
+
+ __asm__ __volatile__(
+
+ "push %%ebp \n"
+
+ "movl %%ecx, %%esi \n"
+ "movl $32, %%ecx \n"
+ "subl %%esi, %%ecx \n" // ecx = 32 - bits
+ "movl $-1, %%edx \n" // edx = -1 (all bits set to one)
+ "shrl %%cl, %%edx \n" // shifting (0 -> edx -> cf) (cl times)
+ "movl %%edx, %%ebp \n" // ebp = edx = mask
+ "movl %%esi, %%ecx \n"
+
+ "xorl %%edx, %%edx \n"
+ "movl %%edx, %%esi \n"
+ "orl %%eax, %%eax \n"
+ "cmovnz %%ebp, %%esi \n" // if(c) esi=mask else esi=0
+
+ "1: \n"
+ "roll %%cl, (%%ebx,%%edx,4) \n"
+
+ "movl (%%ebx,%%edx,4), %%eax \n"
+ "andl %%ebp, %%eax \n"
+ "xorl %%eax, (%%ebx,%%edx,4) \n"
+ "orl %%esi, (%%ebx,%%edx,4) \n"
+ "movl %%eax, %%esi \n"
+
+ "incl %%edx \n"
+ "decl %%edi \n"
+ "jnz 1b \n"
+
+ "and $1, %%eax \n"
+
+ "pop %%ebp \n"
+
+ : "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
+ : "0" (c), "1" (b), "b" (p1), "c" (bits)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Rcl2", c)
+
+ return c;
+ }
+
+
+
+
+ /*!
+ this method moves all bits into the right hand side
+ C -> this -> return value
+
+ the highest *bits* will be held the 'c' and
+ the state of one additional bit (on the right hand side)
+ will be returned
+
+ for example:
+ let this is 000000010
+ after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcr2(uint bits, uint c)
+ {
+ TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+ uint b = value_size;
+ uint * p1 = table;
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+ push esi
+ push edi
+ push ebp
+
+ mov edi, [b]
+
+ mov ecx, 32
+ sub ecx, [bits]
+ mov edx, -1
+ shl edx, cl
+
+ mov ecx, [bits]
+ mov ebx, [p1]
+ mov eax, [c]
+
+ mov ebp, edx // ebp = mask (modified ebp - don't read/write to variables)
+
+ xor edx, edx // edx = 0
+ mov esi, edx
+ add edx, edi
+ dec edx // edx is pointing at the end of the table (on last word)
+ or eax, eax
+ cmovnz esi, ebp // if(c) esi=mask else esi=0
+
+ ttmath_loop:
+ ror dword ptr [ebx+edx*4], cl
+
+ mov eax, [ebx+edx*4]
+ and eax, ebp
+ xor [ebx+edx*4], eax // clearing bits
+ or [ebx+edx*4], esi // saving old value
+ mov esi, eax
+
+ dec edx
+ dec edi
+ jnz ttmath_loop
+
+ pop ebp // restoring ebp
+
+ rol eax, 1 // 31bit will be first
+ and eax, 1
+ mov [c], eax
+
+ pop edi
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2, dummy3;
+
+ __asm__ __volatile__(
+
+ "push %%ebp \n"
+
+ "movl %%ecx, %%esi \n"
+ "movl $32, %%ecx \n"
+ "subl %%esi, %%ecx \n" // ecx = 32 - bits
+ "movl $-1, %%edx \n" // edx = -1 (all bits set to one)
+ "shll %%cl, %%edx \n" // shifting (cf <- edx <- 0) (cl times)
+ "movl %%edx, %%ebp \n" // ebp = edx = mask
+ "movl %%esi, %%ecx \n"
+
+ "xorl %%edx, %%edx \n"
+ "movl %%edx, %%esi \n"
+ "addl %%edi, %%edx \n"
+ "decl %%edx \n" // edx is pointing at the end of the table (on last word)
+ "orl %%eax, %%eax \n"
+ "cmovnz %%ebp, %%esi \n" // if(c) esi=mask else esi=0
+
+ "1: \n"
+ "rorl %%cl, (%%ebx,%%edx,4) \n"
+
+ "movl (%%ebx,%%edx,4), %%eax \n"
+ "andl %%ebp, %%eax \n"
+ "xorl %%eax, (%%ebx,%%edx,4) \n"
+ "orl %%esi, (%%ebx,%%edx,4) \n"
+ "movl %%eax, %%esi \n"
+
+ "decl %%edx \n"
+ "decl %%edi \n"
+ "jnz 1b \n"
+
+ "roll $1, %%eax \n"
+ "andl $1, %%eax \n"
+
+ "pop %%ebp \n"
+
+ : "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
+ : "0" (c), "1" (b), "b" (p1), "c" (bits)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Rcr2", c)
+
+ return c;
+ }
+
+
+#ifdef _MSC_VER
+#pragma warning (default : 4731)
+#endif
+
+
+ /*
+ this method returns the number of the highest set bit in one 32-bit word
+ if the 'x' is zero this method returns '-1'
+ */
+ template<uint value_size>
+ sint UInt<value_size>::FindLeadingBitInWord(uint x)
+ {
+ sint result;
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push eax
+ push edx
+
+ mov edx,-1
+ bsr eax,[x]
+ cmovz eax,edx
+ mov [result], eax
+
+ pop edx
+ pop eax
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy;
+
+ __asm__ (
+
+ "movl $-1, %1 \n"
+ "bsrl %2, %0 \n"
+ "cmovz %1, %0 \n"
+
+ : "=r" (result), "=&r" (dummy)
+ : "r" (x)
+ : "cc" );
+
+ #endif
+
+ return result;
+ }
+
+
+
+ /*
+ this method returns the number of the smallest set bit in one 32-bit word
+ if the 'x' is zero this method returns '-1'
+ */
+ template<uint value_size>
+ sint UInt<value_size>::FindLowestBitInWord(uint x)
+ {
+ sint result;
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push eax
+ push edx
+
+ mov edx,-1
+ bsf eax,[x]
+ cmovz eax,edx
+ mov [result], eax
+
+ pop edx
+ pop eax
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy;
+
+ __asm__ (
+
+ "movl $-1, %1 \n"
+ "bsfl %2, %0 \n"
+ "cmovz %1, %0 \n"
+
+ : "=r" (result), "=&r" (dummy)
+ : "r" (x)
+ : "cc" );
+
+ #endif
+
+ return result;
+ }
+
+
+
+ /*!
+ this method sets a special bit in the 'value'
+ and returns the last state of the bit (zero or one)
+
+ bit is from <0,31>
+ e.g.
+ uint x = 100;
+ uint bit = SetBitInWord(x, 3);
+ now: x = 108 and bit = 0
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
+ {
+ TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
+
+ uint old_bit;
+ uint v = value;
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push ebx
+ push eax
+
+ mov eax, [v]
+ mov ebx, [bit]
+ bts eax, ebx
+ mov [v], eax
+
+ setc bl
+ movzx ebx, bl
+ mov [old_bit], ebx
+
+ pop eax
+ pop ebx
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+ __asm__ (
+
+ "btsl %%ebx, %%eax \n"
+ "setc %%bl \n"
+ "movzx %%bl, %%ebx \n"
+
+ : "=a" (v), "=b" (old_bit)
+ : "0" (v), "1" (bit)
+ : "cc" );
+
+ #endif
+
+ value = v;
+
+ return old_bit;
+ }
+
+
+
+
+ /*!
+ multiplication: result_high:result_low = a * b
+ result_high - higher word of the result
+ result_low - lower word of the result
+
+ this methos never returns a carry
+ this method is used in the second version of the multiplication algorithms
+ */
+ template<uint value_size>
+ void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low)
+ {
+ /*
+ we must use these temporary variables in order to inform the compilator
+ that value pointed with result1 and result2 has changed
+
+ this has no effect in visual studio but it's useful when
+ using gcc and options like -Ox
+ */
+ uint result1_;
+ uint result2_;
+
+ #ifndef __GNUC__
+
+ __asm
+ {
+ push eax
+ push edx
+
+ mov eax, [a]
+ mul dword ptr [b]
+
+ mov [result2_], edx
+ mov [result1_], eax
+
+ pop edx
+ pop eax
+ }
+
+ #endif
+
+
+ #ifdef __GNUC__
+
+ __asm__ (
+
+ "mull %%edx \n"
+
+ : "=a" (result1_), "=d" (result2_)
+ : "0" (a), "1" (b)
+ : "cc" );
+
+ #endif
+
+
+ *result_low = result1_;
+ *result_high = result2_;
+ }
+
+
+
+
+
+ /*!
+ *
+ * Division
+ *
+ *
+ */
+
+
+
+
+ /*!
+ this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
+ r = a:b / c and rest - remainder
+
+ *
+ * WARNING:
+ * if r (one word) is too small for the result or c is equal zero
+ * there'll be a hardware interruption (0)
+ * and probably the end of your program
+ *
+ */
+ template<uint value_size>
+ void UInt<value_size>::DivTwoWords(uint a, uint b, uint c, uint * r, uint * rest)
+ {
+ uint r_;
+ uint rest_;
+ /*
+ these variables have similar meaning like those in
+ the multiplication algorithm MulTwoWords
+ */
+
+ TTMATH_ASSERT( c != 0 )
+
+ #ifndef __GNUC__
+ __asm
+ {
+ push eax
+ push edx
+
+ mov edx, [a]
+ mov eax, [b]
+ div dword ptr [c]
+
+ mov [r_], eax
+ mov [rest_], edx
+
+ pop edx
+ pop eax
+ }
+ #endif
+
+
+ #ifdef __GNUC__
+
+ __asm__ (
+
+ "divl %%ecx \n"
+
+ : "=a" (r_), "=d" (rest_)
+ : "0" (b), "1" (a), "c" (c)
+ : "cc" );
+
+ #endif
+
+
+ *r = r_;
+ *rest = rest_;
+
+ }
+
+
+
+} //namespace
+
+
+
+#endif //ifdef TTMATH_PLATFORM32
+#endif //ifndef TTMATH_NOASM
+#endif
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h
new file mode 100644
index 0000000..188fc5e
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h
@@ -0,0 +1,1146 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa at ttmath.org>
+ */
+
+/*
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name Tomasz Sowa nor the names of contributors to this
+ * project may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef headerfilettmathuint_x86_64
+#define headerfilettmathuint_x86_64
+
+
+#ifndef TTMATH_NOASM
+#ifdef TTMATH_PLATFORM64
+
+
+/*!
+ \file ttmathuint_x86_64.h
+ \brief template class UInt<uint> with assembler code for 64bit x86_64 processors
+
+ this file is included at the end of ttmathuint.h
+*/
+
+#ifndef __GNUC__
+#include <intrin.h>
+#endif
+
+
+namespace ttmath
+{
+
+ #ifndef __GNUC__
+
+ extern "C"
+ {
+ uint __fastcall ttmath_adc_x64(uint* p1, const uint* p2, uint nSize, uint c);
+ uint __fastcall ttmath_addindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
+ uint __fastcall ttmath_addindexed2_x64(uint* p1, uint nSize, uint nPos, uint nValue1, uint nValue2);
+ uint __fastcall ttmath_addvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
+ uint __fastcall ttmath_sbb_x64(uint* p1, const uint* p2, uint nSize, uint c);
+ uint __fastcall ttmath_subindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
+ uint __fastcall ttmath_subvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
+ uint __fastcall ttmath_rcl_x64(uint* p1, uint nSize, uint nLowestBit);
+ uint __fastcall ttmath_rcr_x64(uint* p1, uint nSize, uint nLowestBit);
+ uint __fastcall ttmath_div_x64(uint* pnValHi, uint* pnValLo, uint nDiv);
+ uint __fastcall ttmath_rcl2_x64(uint* p1, uint nSize, uint nBits, uint c);
+ uint __fastcall ttmath_rcr2_x64(uint* p1, uint nSize, uint nBits, uint c);
+ };
+ #endif
+
+
+ /*!
+ returning the string represents the currect type of the library
+ we have following types:
+ asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
+ asm_gcc_32 - with asm code designed for GCC (32 bits)
+ asm_vc_64 - with asm for VC (64 bit)
+ asm_gcc_64 - with asm for GCC (64 bit)
+ no_asm_32 - pure C++ version (32 bit) - without any asm code
+ no_asm_64 - pure C++ version (64 bit) - without any asm code
+ */
+ template<uint value_size>
+ const char * UInt<value_size>::LibTypeStr()
+ {
+ #ifndef __GNUC__
+ static const char info[] = "asm_vc_64";
+ #endif
+
+ #ifdef __GNUC__
+ static const char info[] = "asm_gcc_64";
+ #endif
+
+ return info;
+ }
+
+
+ /*!
+ returning the currect type of the library
+ */
+ template<uint value_size>
+ LibTypeCode UInt<value_size>::LibType()
+ {
+ #ifndef __GNUC__
+ LibTypeCode info = asm_vc_64;
+ #endif
+
+ #ifdef __GNUC__
+ LibTypeCode info = asm_gcc_64;
+ #endif
+
+ return info;
+ }
+
+
+ /*!
+ *
+ * basic mathematic functions
+ *
+ */
+
+
+
+ /*!
+ this method adding ss2 to the this and adding carry if it's defined
+ (this = this + ss2 + c)
+
+ ***this method is created only on a 64bit platform***
+
+ c must be zero or one (might be a bigger value than 1)
+ function returns carry (1) (if it was)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ const uint * p2 = ss2.table;
+
+ // we don't have to use TTMATH_REFERENCE_ASSERT here
+ // this algorithm doesn't require it
+
+ #ifndef __GNUC__
+ c = ttmath_adc_x64(p1,p2,b,c);
+ #endif
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ /*
+ this part should be compiled with gcc
+ */
+ __asm__ __volatile__(
+
+ "xorq %%rdx, %%rdx \n"
+ "negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
+
+ "1: \n"
+ "movq (%%rsi,%%rdx,8), %%rax \n"
+ "adcq %%rax, (%%rbx,%%rdx,8) \n"
+
+ "incq %%rdx \n"
+ "decq %%rcx \n"
+ "jnz 1b \n"
+
+ "adcq %%rcx, %%rcx \n"
+
+ : "=c" (c), "=a" (dummy), "=d" (dummy2)
+ : "0" (b), "1" (c), "b" (p1), "S" (p2)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Add", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this method adds one word (at a specific position)
+ and returns a carry (if it was)
+
+ ***this method is created only on a 64bit platform***
+
+
+ if we've got (value_size=3):
+ table[0] = 10;
+ table[1] = 30;
+ table[2] = 5;
+ and we call:
+ AddInt(2,1)
+ then it'll be:
+ table[0] = 10;
+ table[1] = 30 + 2;
+ table[2] = 5;
+
+ of course if there was a carry from table[2] it would be returned
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddInt(uint value, uint index)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ uint c;
+
+ TTMATH_ASSERT( index < value_size )
+
+ #ifndef __GNUC__
+ c = ttmath_addindexed_x64(p1,b,index,value);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "subq %%rdx, %%rcx \n"
+
+ "1: \n"
+ "addq %%rax, (%%rbx,%%rdx,8) \n"
+ "jnc 2f \n"
+
+ "movq $1, %%rax \n"
+ "incq %%rdx \n"
+ "decq %%rcx \n"
+ "jnz 1b \n"
+
+ "2: \n"
+ "setc %%al \n"
+ "movzx %%al, %%rdx \n"
+
+ : "=d" (c), "=a" (dummy), "=c" (dummy2)
+ : "0" (index), "1" (value), "2" (b), "b" (p1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::AddInt", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this method adds only two unsigned words to the existing value
+ and these words begin on the 'index' position
+ (it's used in the multiplication algorithm 2)
+
+ ***this method is created only on a 64bit platform***
+
+ index should be equal or smaller than value_size-2 (index <= value_size-2)
+ x1 - lower word, x2 - higher word
+
+ for example if we've got value_size equal 4 and:
+ table[0] = 3
+ table[1] = 4
+ table[2] = 5
+ table[3] = 6
+ then let
+ x1 = 10
+ x2 = 20
+ and
+ index = 1
+
+ the result of this method will be:
+ table[0] = 3
+ table[1] = 4 + x1 = 14
+ table[2] = 5 + x2 = 25
+ table[3] = 6
+
+ and no carry at the end of table[3]
+
+ (of course if there was a carry in table[2](5+20) then
+ this carry would be passed to the table[3] etc.)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ uint c;
+
+ TTMATH_ASSERT( index < value_size - 1 )
+
+ #ifndef __GNUC__
+ c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "subq %%rdx, %%rcx \n"
+
+ "addq %%rsi, (%%rbx,%%rdx,8) \n"
+ "incq %%rdx \n"
+ "decq %%rcx \n"
+
+ "1: \n"
+ "adcq %%rax, (%%rbx,%%rdx,8) \n"
+ "jnc 2f \n"
+
+ "mov $0, %%rax \n"
+ "incq %%rdx \n"
+ "decq %%rcx \n"
+ "jnz 1b \n"
+
+ "2: \n"
+ "setc %%al \n"
+ "movzx %%al, %%rax \n"
+
+ : "=a" (c), "=c" (dummy), "=d" (dummy2)
+ : "0" (x2), "1" (b), "2" (index), "b" (p1), "S" (x1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::AddTwoInts", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this static method addes one vector to the other
+ 'ss1' is larger in size or equal to 'ss2'
+
+ ss1 points to the first (larger) vector
+ ss2 points to the second vector
+ ss1_size - size of the ss1 (and size of the result too)
+ ss2_size - size of the ss2
+ result - is the result vector (which has size the same as ss1: ss1_size)
+
+ Example: ss1_size is 5, ss2_size is 3
+ ss1: ss2: result (output):
+ 5 1 5+1
+ 4 3 4+3
+ 2 7 2+7
+ 6 6
+ 9 9
+ of course the carry is propagated and will be returned from the last item
+ (this method is used by the Karatsuba multiplication algorithm)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+ {
+ TTMATH_ASSERT( ss1_size >= ss2_size )
+
+ uint c;
+
+ #ifndef __GNUC__
+ c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy1, dummy2, dummy3;
+ uint rest = ss1_size - ss2_size;
+
+ // this part should be compiled with gcc
+
+ __asm__ __volatile__(
+ "mov %%rdx, %%r8 \n"
+ "xor %%rdx, %%rdx \n" // rdx = 0, cf = 0
+ "1: \n"
+ "mov (%%rsi,%%rdx,8), %%rax \n"
+ "adc (%%rbx,%%rdx,8), %%rax \n"
+ "mov %%rax, (%%rdi,%%rdx,8) \n"
+
+ "inc %%rdx \n"
+ "dec %%rcx \n"
+ "jnz 1b \n"
+
+ "adc %%rcx, %%rcx \n" // rcx has the cf state
+
+ "or %%r8, %%r8 \n"
+ "jz 3f \n"
+
+ "xor %%rbx, %%rbx \n" // ebx = 0
+ "neg %%rcx \n" // setting cf from rcx
+ "mov %%r8, %%rcx \n" // rcx=rest and is != 0
+ "2: \n"
+ "mov (%%rsi, %%rdx, 8), %%rax \n"
+ "adc %%rbx, %%rax \n"
+ "mov %%rax, (%%rdi, %%rdx, 8) \n"
+
+ "inc %%rdx \n"
+ "dec %%rcx \n"
+ "jnz 2b \n"
+
+ "adc %%rcx, %%rcx \n"
+ "3: \n"
+
+ : "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3)
+ : "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result)
+ : "%r8", "cc", "memory" );
+
+ #endif
+
+ TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
+
+ return c;
+ }
+
+
+
+ /*!
+ this method's subtracting ss2 from the 'this' and subtracting
+ carry if it has been defined
+ (this = this - ss2 - c)
+
+ ***this method is created only on a 64bit platform***
+
+ c must be zero or one (might be a bigger value than 1)
+ function returns carry (1) (if it was)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ const uint * p2 = ss2.table;
+
+ // we don't have to use TTMATH_REFERENCE_ASSERT here
+ // this algorithm doesn't require it
+
+ #ifndef __GNUC__
+ c = ttmath_sbb_x64(p1,p2,b,c);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "xorq %%rdx, %%rdx \n"
+ "negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
+
+ "1: \n"
+ "movq (%%rsi,%%rdx,8), %%rax \n"
+ "sbbq %%rax, (%%rbx,%%rdx,8) \n"
+
+ "incq %%rdx \n"
+ "decq %%rcx \n"
+ "jnz 1b \n"
+
+ "adcq %%rcx, %%rcx \n"
+
+ : "=c" (c), "=a" (dummy), "=d" (dummy2)
+ : "0" (b), "1" (c), "b" (p1), "S" (p2)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Sub", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this method subtracts one word (at a specific position)
+ and returns a carry (if it was)
+
+ ***this method is created only on a 64bit platform***
+
+ if we've got (value_size=3):
+ table[0] = 10;
+ table[1] = 30;
+ table[2] = 5;
+ and we call:
+ SubInt(2,1)
+ then it'll be:
+ table[0] = 10;
+ table[1] = 30 - 2;
+ table[2] = 5;
+
+ of course if there was a carry from table[2] it would be returned
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SubInt(uint value, uint index)
+ {
+ uint b = value_size;
+ uint * p1 = table;
+ uint c;
+
+ TTMATH_ASSERT( index < value_size )
+
+ #ifndef __GNUC__
+ c = ttmath_subindexed_x64(p1,b,index,value);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "subq %%rdx, %%rcx \n"
+
+ "1: \n"
+ "subq %%rax, (%%rbx,%%rdx,8) \n"
+ "jnc 2f \n"
+
+ "movq $1, %%rax \n"
+ "incq %%rdx \n"
+ "decq %%rcx \n"
+ "jnz 1b \n"
+
+ "2: \n"
+ "setc %%al \n"
+ "movzx %%al, %%rdx \n"
+
+ : "=d" (c), "=a" (dummy), "=c" (dummy2)
+ : "0" (index), "1" (value), "2" (b), "b" (p1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::SubInt", c)
+
+ return c;
+ }
+
+
+ /*!
+ this static method subtractes one vector from the other
+ 'ss1' is larger in size or equal to 'ss2'
+
+ ss1 points to the first (larger) vector
+ ss2 points to the second vector
+ ss1_size - size of the ss1 (and size of the result too)
+ ss2_size - size of the ss2
+ result - is the result vector (which has size the same as ss1: ss1_size)
+
+ Example: ss1_size is 5, ss2_size is 3
+ ss1: ss2: result (output):
+ 5 1 5-1
+ 4 3 4-3
+ 2 7 2-7
+ 6 6-1 (the borrow from previous item)
+ 9 9
+ return (carry): 0
+ of course the carry (borrow) is propagated and will be returned from the last item
+ (this method is used by the Karatsuba multiplication algorithm)
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+ {
+ TTMATH_ASSERT( ss1_size >= ss2_size )
+
+ uint c;
+
+ #ifndef __GNUC__
+ c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
+ #endif
+
+
+ #ifdef __GNUC__
+
+ // the asm code is nearly the same as in AddVector
+ // only two instructions 'adc' are changed to 'sbb'
+
+ uint dummy1, dummy2, dummy3;
+ uint rest = ss1_size - ss2_size;
+
+ __asm__ __volatile__(
+ "mov %%rdx, %%r8 \n"
+ "xor %%rdx, %%rdx \n" // rdx = 0, cf = 0
+ "1: \n"
+ "mov (%%rsi,%%rdx,8), %%rax \n"
+ "sbb (%%rbx,%%rdx,8), %%rax \n"
+ "mov %%rax, (%%rdi,%%rdx,8) \n"
+
+ "inc %%rdx \n"
+ "dec %%rcx \n"
+ "jnz 1b \n"
+
+ "adc %%rcx, %%rcx \n" // rcx has the cf state
+
+ "or %%r8, %%r8 \n"
+ "jz 3f \n"
+
+ "xor %%rbx, %%rbx \n" // ebx = 0
+ "neg %%rcx \n" // setting cf from rcx
+ "mov %%r8, %%rcx \n" // rcx=rest and is != 0
+ "2: \n"
+ "mov (%%rsi, %%rdx, 8), %%rax \n"
+ "sbb %%rbx, %%rax \n"
+ "mov %%rax, (%%rdi, %%rdx, 8) \n"
+
+ "inc %%rdx \n"
+ "dec %%rcx \n"
+ "jnz 2b \n"
+
+ "adc %%rcx, %%rcx \n"
+ "3: \n"
+
+ : "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3)
+ : "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result)
+ : "%r8", "cc", "memory" );
+
+ #endif
+
+ TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
+
+ return c;
+ }
+
+
+ /*!
+ this method moves all bits into the left hand side
+ return value <- this <- c
+
+ the lowest *bit* will be held the 'c' and
+ the state of one additional bit (on the left hand side)
+ will be returned
+
+ for example:
+ let this is 001010000
+ after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0
+
+ ***this method is created only on a 64bit platform***
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcl2_one(uint c)
+ {
+ sint b = value_size;
+ uint * p1 = table;
+
+
+ #ifndef __GNUC__
+ c = ttmath_rcl_x64(p1,b,c);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2;
+
+ __asm__ __volatile__(
+
+ "xorq %%rdx, %%rdx \n" // rdx=0
+ "negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
+
+ "1: \n"
+ "rclq $1, (%%rbx, %%rdx, 8) \n"
+
+ "incq %%rdx \n"
+ "decq %%rcx \n"
+ "jnz 1b \n"
+
+ "adcq %%rcx, %%rcx \n"
+
+ : "=c" (c), "=a" (dummy), "=d" (dummy2)
+ : "0" (b), "1" (c), "b" (p1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Rcl2_one", c)
+
+ return c;
+ }
+
+
+ /*!
+ this method moves all bits into the right hand side
+ c -> this -> return value
+
+ the highest *bit* will be held the 'c' and
+ the state of one additional bit (on the right hand side)
+ will be returned
+
+ for example:
+ let this is 000000010
+ after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
+
+ ***this method is created only on a 64bit platform***
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcr2_one(uint c)
+ {
+ sint b = value_size;
+ uint * p1 = table;
+
+
+ #ifndef __GNUC__
+ c = ttmath_rcr_x64(p1,b,c);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy;
+
+ __asm__ __volatile__(
+
+ "negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
+
+ "1: \n"
+ "rcrq $1, -8(%%rbx, %%rcx, 8) \n"
+
+ "decq %%rcx \n"
+ "jnz 1b \n"
+
+ "adcq %%rcx, %%rcx \n"
+
+ : "=c" (c), "=a" (dummy)
+ : "0" (b), "1" (c), "b" (p1)
+ : "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Rcr2_one", c)
+
+ return c;
+ }
+
+
+
+ /*!
+ this method moves all bits into the left hand side
+ return value <- this <- c
+
+ the lowest *bits* will be held the 'c' and
+ the state of one additional bit (on the left hand side)
+ will be returned
+
+ for example:
+ let this is 001010000
+ after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
+
+ ***this method is created only on a 64bit platform***
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcl2(uint bits, uint c)
+ {
+ TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+ uint b = value_size;
+ uint * p1 = table;
+
+
+ #ifndef __GNUC__
+ c = ttmath_rcl2_x64(p1,b,bits,c);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2, dummy3;
+
+ __asm__ __volatile__(
+
+ "movq %%rcx, %%rsi \n"
+ "movq $64, %%rcx \n"
+ "subq %%rsi, %%rcx \n"
+ "movq $-1, %%rdx \n"
+ "shrq %%cl, %%rdx \n"
+ "movq %%rdx, %%r8 \n"
+ "movq %%rsi, %%rcx \n"
+
+ "xorq %%rdx, %%rdx \n"
+ "movq %%rdx, %%rsi \n"
+ "orq %%rax, %%rax \n"
+ "cmovnz %%r8, %%rsi \n"
+
+ "1: \n"
+ "rolq %%cl, (%%rbx,%%rdx,8) \n"
+
+ "movq (%%rbx,%%rdx,8), %%rax \n"
+ "andq %%r8, %%rax \n"
+ "xorq %%rax, (%%rbx,%%rdx,8) \n"
+ "orq %%rsi, (%%rbx,%%rdx,8) \n"
+ "movq %%rax, %%rsi \n"
+
+ "incq %%rdx \n"
+ "decq %%rdi \n"
+ "jnz 1b \n"
+
+ "and $1, %%rax \n"
+
+ : "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
+ : "0" (c), "1" (b), "b" (p1), "c" (bits)
+ : "%r8", "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Rcl2", c)
+
+ return c;
+ }
+
+
+ /*!
+ this method moves all bits into the right hand side
+ C -> this -> return value
+
+ the highest *bits* will be held the 'c' and
+ the state of one additional bit (on the right hand side)
+ will be returned
+
+ for example:
+ let this is 000000010
+ after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
+
+ ***this method is created only on a 64bit platform***
+ */
+ template<uint value_size>
+ uint UInt<value_size>::Rcr2(uint bits, uint c)
+ {
+ TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+ sint b = value_size;
+ uint * p1 = table;
+
+
+ #ifndef __GNUC__
+ c = ttmath_rcr2_x64(p1,b,bits,c);
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy, dummy2, dummy3;
+
+ __asm__ __volatile__(
+
+ "movq %%rcx, %%rsi \n"
+ "movq $64, %%rcx \n"
+ "subq %%rsi, %%rcx \n"
+ "movq $-1, %%rdx \n"
+ "shlq %%cl, %%rdx \n"
+ "movq %%rdx, %%R8 \n"
+ "movq %%rsi, %%rcx \n"
+
+ "xorq %%rdx, %%rdx \n"
+ "movq %%rdx, %%rsi \n"
+ "addq %%rdi, %%rdx \n"
+ "decq %%rdx \n"
+ "orq %%rax, %%rax \n"
+ "cmovnz %%R8, %%rsi \n"
+
+ "1: \n"
+ "rorq %%cl, (%%rbx,%%rdx,8) \n"
+
+ "movq (%%rbx,%%rdx,8), %%rax \n"
+ "andq %%R8, %%rax \n"
+ "xorq %%rax, (%%rbx,%%rdx,8) \n"
+ "orq %%rsi, (%%rbx,%%rdx,8) \n"
+ "movq %%rax, %%rsi \n"
+
+ "decq %%rdx \n"
+ "decq %%rdi \n"
+ "jnz 1b \n"
+
+ "rolq $1, %%rax \n"
+ "andq $1, %%rax \n"
+
+ : "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
+ : "0" (c), "1" (b), "b" (p1), "c" (bits)
+ : "%r8", "cc", "memory" );
+
+ #endif
+
+ TTMATH_LOGC("UInt::Rcr2", c)
+
+ return c;
+ }
+
+
+ /*
+ this method returns the number of the highest set bit in one 64-bit word
+ if the 'x' is zero this method returns '-1'
+
+ ***this method is created only on a 64bit platform***
+ */
+ template<uint value_size>
+ sint UInt<value_size>::FindLeadingBitInWord(uint x)
+ {
+ sint result;
+
+
+ #ifndef __GNUC__
+
+ unsigned long nIndex = 0;
+
+ if( _BitScanReverse64(&nIndex,x) == 0 )
+ result = -1;
+ else
+ result = nIndex;
+
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy;
+
+ __asm__ (
+
+ "movq $-1, %1 \n"
+ "bsrq %2, %0 \n"
+ "cmovz %1, %0 \n"
+
+ : "=r" (result), "=&r" (dummy)
+ : "r" (x)
+ : "cc" );
+
+ #endif
+
+
+ return result;
+ }
+
+
+ /*
+ this method returns the number of the highest set bit in one 64-bit word
+ if the 'x' is zero this method returns '-1'
+
+ ***this method is created only on a 64bit platform***
+ */
+ template<uint value_size>
+ sint UInt<value_size>::FindLowestBitInWord(uint x)
+ {
+ sint result;
+
+
+ #ifndef __GNUC__
+
+ unsigned long nIndex = 0;
+
+ if( _BitScanForward64(&nIndex,x) == 0 )
+ result = -1;
+ else
+ result = nIndex;
+
+ #endif
+
+
+ #ifdef __GNUC__
+ uint dummy;
+
+ __asm__ (
+
+ "movq $-1, %1 \n"
+ "bsfq %2, %0 \n"
+ "cmovz %1, %0 \n"
+
+ : "=r" (result), "=&r" (dummy)
+ : "r" (x)
+ : "cc" );
+
+ #endif
+
+
+ return result;
+ }
+
+
+ /*!
+ this method sets a special bit in the 'value'
+ and returns the last state of the bit (zero or one)
+
+ ***this method is created only on a 64bit platform***
+
+ bit is from <0,63>
+
+ e.g.
+ uint x = 100;
+ uint bit = SetBitInWord(x, 3);
+ now: x = 108 and bit = 0
+ */
+ template<uint value_size>
+ uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
+ {
+ TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
+
+ uint old_bit;
+ uint v = value;
+
+
+ #ifndef __GNUC__
+ old_bit = _bittestandset64((__int64*)&value,bit) != 0;
+ #endif
+
+
+ #ifdef __GNUC__
+
+ __asm__ (
+
+ "btsq %%rbx, %%rax \n"
+ "setc %%bl \n"
+ "movzx %%bl, %%rbx \n"
+
+ : "=a" (v), "=b" (old_bit)
+ : "0" (v), "1" (bit)
+ : "cc" );
+
+ #endif
+
+ value = v;
+
+ return old_bit;
+ }
+
+
+ /*!
+ *
+ * Multiplication
+ *
+ *
+ */
+
+
+ /*!
+ multiplication: result_high:result_low = a * b
+ result_high - higher word of the result
+ result_low - lower word of the result
+
+ this methos never returns a carry
+ this method is used in the second version of the multiplication algorithms
+
+ ***this method is created only on a 64bit platform***
+ */
+ template<uint value_size>
+ void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low)
+ {
+ /*
+ we must use these temporary variables in order to inform the compilator
+ that value pointed with result1 and result2 has changed
+
+ this has no effect in visual studio but it's usefull when
+ using gcc and options like -O
+ */
+ uint result1_;
+ uint result2_;
+
+
+ #ifndef __GNUC__
+ result1_ = _umul128(a,b,&result2_);
+ #endif
+
+
+ #ifdef __GNUC__
+
+ __asm__ (
+
+ "mulq %%rdx \n"
+
+ : "=a" (result1_), "=d" (result2_)
+ : "0" (a), "1" (b)
+ : "cc" );
+
+ #endif
+
+
+ *result_low = result1_;
+ *result_high = result2_;
+ }
+
+
+
+
+ /*!
+ *
+ * Division
+ *
+ *
+ */
+
+
+ /*!
+ this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
+ r = a:b / c and rest - remainder
+
+ ***this method is created only on a 64bit platform***
+
+ *
+ * WARNING:
+ * if r (one word) is too small for the result or c is equal zero
+ * there'll be a hardware interruption (0)
+ * and probably the end of your program
+ *
+ */
+ template<uint value_size>
+ void UInt<value_size>::DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest)
+ {
+ uint r_;
+ uint rest_;
+ /*
+ these variables have similar meaning like those in
+ the multiplication algorithm MulTwoWords
+ */
+
+ TTMATH_ASSERT( c != 0 )
+
+
+ #ifndef __GNUC__
+
+ ttmath_div_x64(&a,&b,c);
+ r_ = a;
+ rest_ = b;
+
+ #endif
+
+
+ #ifdef __GNUC__
+
+ __asm__ (
+
+ "divq %%rcx \n"
+
+ : "=a" (r_), "=d" (rest_)
+ : "d" (a), "a" (b), "c" (c)
+ : "cc" );
+
+ #endif
+
+
+ *r = r_;
+ *rest = rest_;
+ }
+
+} //namespace
+
+
+#endif //ifdef TTMATH_PLATFORM64
+#endif //ifndef TTMATH_NOASM
+#endif
+
+
diff --git a/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm
new file mode 100644
index 0000000..b7c85c2
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm
@@ -0,0 +1,548 @@
+;
+; This file is a part of TTMath Bignum Library
+; and is distributed under the (new) BSD licence.
+; Author: Christian Kaiser <chk at online.de>
+;
+
+;
+; Copyright (c) 2009, Christian Kaiser
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are met:
+;
+; * Redistributions of source code must retain the above copyright notice,
+; this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+;
+; * Neither the name Christian Kaiser nor the names of contributors to this
+; project may be used to endorse or promote products derived
+; from this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+;
+
+;
+; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
+; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
+; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
+;
+
+PUBLIC ttmath_adc_x64
+PUBLIC ttmath_addindexed_x64
+PUBLIC ttmath_addindexed2_x64
+PUBLIC ttmath_addvector_x64
+
+PUBLIC ttmath_sbb_x64
+PUBLIC ttmath_subindexed_x64
+PUBLIC ttmath_subvector_x64
+
+PUBLIC ttmath_rcl_x64
+PUBLIC ttmath_rcr_x64
+
+PUBLIC ttmath_rcl2_x64
+PUBLIC ttmath_rcr2_x64
+
+PUBLIC ttmath_div_x64
+
+;
+; Microsoft x86_64 convention: http://msdn.microsoft.com/en-us/library/9b372w95.aspx
+;
+; "rax, rcx, rdx, r8-r11 are volatile."
+; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile."
+;
+
+
+.CODE
+
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_adc_x64 PROC
+ ; rcx = p1
+ ; rdx = p2
+ ; r8 = nSize
+ ; r9 = nCarry
+
+ xor rax, rax
+ xor r11, r11
+ sub rax, r9 ; sets CARRY if r9 != 0
+
+ ALIGN 16
+ loop1:
+ mov rax,qword ptr [rdx + r11 * 8]
+ adc qword ptr [rcx + r11 * 8], rax
+ lea r11, [r11+1]
+ dec r8
+ jnz loop1
+
+ setc al
+ movzx rax, al
+
+ ret
+
+ttmath_adc_x64 ENDP
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_addindexed_x64 PROC
+
+ ; rcx = p1
+ ; rdx = nSize
+ ; r8 = nPos
+ ; r9 = nValue
+
+ xor rax, rax ; rax = result
+ sub rdx, r8 ; rdx = remaining count of uints
+
+ add qword ptr [rcx + r8 * 8], r9
+ jc next1
+
+ ret
+
+next1:
+ mov r9, 1
+
+ ALIGN 16
+loop1:
+ dec rdx
+ jz done_with_cy
+ lea r8, [r8+1]
+ add qword ptr [rcx + r8 * 8], r9
+ jc loop1
+
+ ret
+
+done_with_cy:
+ lea rax, [rax+1] ; rax = 1
+
+ ret
+
+ttmath_addindexed_x64 ENDP
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_addindexed2_x64 PROC
+
+ ; rcx = p1 (pointer)
+ ; rdx = b (value size)
+ ; r8 = nPos
+ ; r9 = nValue1
+ ; [esp+0x28] = nValue2
+
+ xor rax, rax ; return value
+ mov r11, rcx ; table
+ sub rdx, r8 ; rdx = remaining count of uints
+ mov r10, [esp+028h] ; r10 = nValue2
+
+ add qword ptr [r11 + r8 * 8], r9
+ lea r8, [r8+1]
+ lea rdx, [rdx-1]
+ adc qword ptr [r11 + r8 * 8], r10
+ jc next
+ ret
+
+ ALIGN 16
+loop1:
+ lea r8, [r8+1]
+ add qword ptr [r11 + r8 * 8], 1
+ jc next
+ ret
+
+next:
+ dec rdx ; does not modify CY too...
+ jnz loop1
+ lea rax, [rax+1]
+ ret
+
+ttmath_addindexed2_x64 ENDP
+
+
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+
+ttmath_addvector_x64 PROC
+ ; rcx = ss1
+ ; rdx = ss2
+ ; r8 = ss1_size
+ ; r9 = ss2_size
+ ; [esp+0x28] = result
+
+ mov r10, [esp+028h]
+ sub r8, r9
+ xor r11, r11 ; r11=0, cf=0
+
+ ALIGN 16
+ loop1:
+ mov rax, qword ptr [rcx + r11 * 8]
+ adc rax, qword ptr [rdx + r11 * 8]
+ mov qword ptr [r10 + r11 * 8], rax
+ inc r11
+ dec r9
+ jnz loop1
+
+ adc r9, r9 ; r9 has the cf state
+
+ or r8, r8
+ jz done
+
+ neg r9 ; setting cf from r9
+ mov r9, 0 ; don't use xor here (cf is used)
+ loop2:
+ mov rax, qword ptr [rcx + r11 * 8]
+ adc rax, r9
+ mov qword ptr [r10 + r11 * 8], rax
+ inc r11
+ dec r8
+ jnz loop2
+
+ adc r8, r8
+ mov rax, r8
+
+ ret
+
+done:
+ mov rax, r9
+ ret
+
+ttmath_addvector_x64 ENDP
+
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_sbb_x64 PROC
+
+ ; rcx = p1
+ ; rdx = p2
+ ; r8 = nCount
+ ; r9 = nCarry
+
+ xor rax, rax
+ xor r11, r11
+ sub rax, r9 ; sets CARRY if r9 != 0
+
+ ALIGN 16
+ loop1:
+ mov rax,qword ptr [rdx + r11 * 8]
+ sbb qword ptr [rcx + r11 * 8], rax
+ lea r11, [r11+1]
+ dec r8
+ jnz loop1
+
+ setc al
+ movzx rax, al
+
+ ret
+
+ttmath_sbb_x64 ENDP
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_subindexed_x64 PROC
+ ; rcx = p1
+ ; rdx = nSize
+ ; r8 = nPos
+ ; r9 = nValue
+
+ sub rdx, r8 ; rdx = remaining count of uints
+
+ ALIGN 16
+loop1:
+ sub qword ptr [rcx + r8 * 8], r9
+ jnc done
+
+ lea r8, [r8+1]
+ mov r9, 1
+ dec rdx
+ jnz loop1
+
+ mov rax, 1
+ ret
+
+done:
+ xor rax, rax
+ ret
+
+ttmath_subindexed_x64 ENDP
+
+
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+; the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb'
+
+ttmath_subvector_x64 PROC
+ ; rcx = ss1
+ ; rdx = ss2
+ ; r8 = ss1_size
+ ; r9 = ss2_size
+ ; [esp+0x28] = result
+
+ mov r10, [esp+028h]
+ sub r8, r9
+ xor r11, r11 ; r11=0, cf=0
+
+ ALIGN 16
+ loop1:
+ mov rax, qword ptr [rcx + r11 * 8]
+ sbb rax, qword ptr [rdx + r11 * 8]
+ mov qword ptr [r10 + r11 * 8], rax
+ inc r11
+ dec r9
+ jnz loop1
+
+ adc r9, r9 ; r9 has the cf state
+
+ or r8, r8
+ jz done
+
+ neg r9 ; setting cf from r9
+ mov r9, 0 ; don't use xor here (cf is used)
+ loop2:
+ mov rax, qword ptr [rcx + r11 * 8]
+ sbb rax, r9
+ mov qword ptr [r10 + r11 * 8], rax
+ inc r11
+ dec r8
+ jnz loop2
+
+ adc r8, r8
+ mov rax, r8
+
+ ret
+
+done:
+ mov rax, r9
+ ret
+
+ttmath_subvector_x64 ENDP
+
+
+
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_rcl_x64 PROC
+ ; rcx = p1
+ ; rdx = b
+ ; r8 = nLowestBit
+
+ mov r11, rcx ; table
+ xor r10, r10
+ neg r8 ; CY set if r8 <> 0
+
+ ALIGN 16
+loop1:
+ rcl qword ptr [r11 + r10 * 8], 1
+ lea r10, [r10+1]
+ dec rdx
+ jnz loop1
+
+ setc al
+ movzx rax, al
+
+ ret
+
+ttmath_rcl_x64 ENDP
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_rcr_x64 PROC
+ ; rcx = p1
+ ; rdx = nSize
+ ; r8 = nLowestBit
+
+ xor r10, r10
+ neg r8 ; CY set if r8 <> 0
+
+ ALIGN 16
+loop1:
+ rcr qword ptr -8[rcx + rdx * 8], 1
+ dec rdx
+ jnz loop1
+
+ setc al
+ movzx rax, al
+
+ ret
+
+ttmath_rcr_x64 ENDP
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_div_x64 PROC
+
+ ; rcx = &Hi
+ ; rdx = &Lo
+ ; r8 = nDiv
+
+ mov r11, rcx
+ mov r10, rdx
+
+ mov rdx, qword ptr [r11]
+ mov rax, qword ptr [r10]
+ div r8
+ mov qword ptr [r10], rdx ; remainder
+ mov qword ptr [r11], rax ; value
+
+ ret
+
+ttmath_div_x64 ENDP
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_rcl2_x64 PROC
+ ; rcx = p1
+ ; rdx = nSize
+ ; r8 = bits
+ ; r9 = c
+
+ push rbx
+
+ mov r10, rcx ; r10 = p1
+ xor rax, rax
+
+ mov rcx, 64
+ sub rcx, r8
+
+ mov r11, -1
+ shr r11, cl ; r11 = mask
+
+ mov rcx, r8 ; rcx = count of bits
+
+ mov rbx, rax ; rbx = old value = 0
+ or r9, r9
+ cmovnz rbx, r11 ; if (c) then old value = mask
+
+ mov r9, rax ; r9 = index (0..nSize-1)
+
+ ALIGN 16
+loop1:
+ rol qword ptr [r10+r9*8], cl
+ mov rax, qword ptr [r10+r9*8]
+ and rax, r11
+ xor qword ptr [r10+r9*8], rax
+ or qword ptr [r10+r9*8], rbx
+ mov rbx, rax
+
+ lea r9, [r9+1]
+ dec rdx
+
+ jnz loop1
+
+ and rax, 1
+ pop rbx
+ ret
+
+ttmath_rcl2_x64 ENDP
+
+;----------------------------------------
+
+ ALIGN 8
+
+;----------------------------------------
+
+ttmath_rcr2_x64 PROC
+ ; rcx = p1
+ ; rdx = nSize
+ ; r8 = bits
+ ; r9 = c
+
+ push rbx
+ mov r10, rcx ; r10 = p1
+ xor rax, rax
+
+ mov rcx, 64
+ sub rcx, r8
+
+ mov r11, -1
+ shl r11, cl ; r11 = mask
+
+ mov rcx, r8 ; rcx = count of bits
+
+ mov rbx, rax ; rbx = old value = 0
+ or r9, r9
+ cmovnz rbx, r11 ; if (c) then old value = mask
+
+ mov r9, rdx ; r9 = index (0..nSize-1)
+ lea r9, [r9-1]
+
+ ALIGN 16
+loop1:
+ ror qword ptr [r10+r9*8], cl
+ mov rax, qword ptr [r10+r9*8]
+ and rax, r11
+ xor qword ptr [r10+r9*8], rax
+ or qword ptr [r10+r9*8], rbx
+ mov rbx, rax
+
+ lea r9, [r9-1]
+ dec rdx
+
+ jnz loop1
+
+ rol rax, 1
+ and rax, 1
+ pop rbx
+
+ ret
+
+ttmath_rcr2_x64 ENDP
+
+END
diff --git a/src/boost/geometry/extensions/contrib/ttmath_stub.hpp b/src/boost/geometry/extensions/contrib/ttmath_stub.hpp
new file mode 100644
index 0000000..50da4c0
--- /dev/null
+++ b/src/boost/geometry/extensions/contrib/ttmath_stub.hpp
@@ -0,0 +1,293 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef TTMATH_STUB
+#define TTMATH_STUB
+
+#include <boost/math/constants/constants.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/coordinate_cast.hpp>
+
+
+#include <ttmath.h>
+namespace ttmath
+{
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> sqrt(Big<Exponent, Mantissa> const& v)
+ {
+ return Sqrt(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> abs(Big<Exponent, Mantissa> const& v)
+ {
+ return Abs(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> ceil(Big<Exponent, Mantissa> const& v)
+ {
+ return Ceil(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> floor(Big<Exponent, Mantissa> const& v)
+ {
+ return Floor(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> asin(Big<Exponent, Mantissa> const& v)
+ {
+ return ASin(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> sin(Big<Exponent, Mantissa> const& v)
+ {
+ return Sin(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> cos(Big<Exponent, Mantissa> const& v)
+ {
+ return Cos(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> tan(Big<Exponent, Mantissa> const& v)
+ {
+ return Tan(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> atan(Big<Exponent, Mantissa> const& v)
+ {
+ return ATan(v);
+ }
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> acos(Big<Exponent, Mantissa> const& v)
+ {
+ return ACos(v);
+ }
+
+
+ template <uint Exponent, uint Mantissa>
+ inline Big<Exponent, Mantissa> atan2(Big<Exponent, Mantissa> const& y, Big<Exponent, Mantissa> const& x)
+ {
+ // return ATan2(y, 2); does not (yet) exist in ttmath...
+
+ // See http://en.wikipedia.org/wiki/Atan2
+
+ Big<Exponent, Mantissa> const zero(0);
+ Big<Exponent, Mantissa> const two(2);
+
+ if (y == zero)
+ {
+ // return x >= 0 ? 0 : pi and pi=2*arccos(0)
+ return x >= zero ? zero : two * ACos(zero);
+ }
+
+ return two * ATan((sqrt(x * x + y * y) - x) / y);
+ }
+
+}
+
+// Specific structure implementing constructor
+// (WHICH IS NECESSARY FOR Boost.Geometry because it enables using T() !! )
+struct ttmath_big : ttmath::Big<1,4>
+{
+ ttmath_big(double v = 0)
+ : ttmath::Big<1,4>(v)
+ {}
+ ttmath_big(ttmath::Big<1,4> const& v)
+ : ttmath::Big<1,4>(v)
+ {}
+
+ /*
+ inline operator double() const
+ {
+ return atof(this->ToString().c_str());
+ }
+
+ inline operator int() const
+ {
+ return atol(ttmath::Round(*this).ToString().c_str());
+ }
+ */
+};
+
+namespace boost{ namespace geometry { namespace math
+{
+
+namespace detail
+{
+ // Workaround for boost::math::constants::pi:
+ // 1) lexical cast -> stack overflow and
+ // 2) because it is implemented as a function, generic implementation not possible
+
+ // Partial specialization for ttmath
+ template <ttmath::uint Exponent, ttmath::uint Mantissa>
+ struct define_pi<ttmath::Big<Exponent, Mantissa> >
+ {
+ static inline ttmath::Big<Exponent, Mantissa> apply()
+ {
+ static ttmath::Big<Exponent, Mantissa> const the_pi(
+ "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196");
+ return the_pi;
+ }
+ };
+
+ template <>
+ struct define_pi<ttmath_big>
+ : public define_pi<ttmath::Big<1,4> >
+ {};
+
+ template <ttmath::uint Exponent, ttmath::uint Mantissa>
+ struct equals_with_epsilon<ttmath::Big<Exponent, Mantissa>, false>
+ {
+ static inline bool apply(ttmath::Big<Exponent, Mantissa> const& a, ttmath::Big<Exponent, Mantissa> const& b)
+ {
+ // See implementation in util/math.hpp
+ // But here borrow the tolerance for double, to avoid exact comparison
+ ttmath::Big<Exponent, Mantissa> const epsilon = std::numeric_limits<double>::epsilon();
+ return ttmath::Abs(a - b) <= epsilon * ttmath::Abs(a);
+ }
+ };
+
+ template <>
+ struct equals_with_epsilon<ttmath_big, false>
+ : public equals_with_epsilon<ttmath::Big<1, 4>, false>
+ {};
+
+} // detail
+
+} // ttmath
+
+
+namespace detail
+{
+
+template <ttmath::uint Exponent, ttmath::uint Mantissa>
+struct coordinate_cast<ttmath::Big<Exponent, Mantissa> >
+{
+ static inline ttmath::Big<Exponent, Mantissa> apply(std::string const& source)
+ {
+ return ttmath::Big<Exponent, Mantissa> (source);
+ }
+};
+
+
+template <>
+struct coordinate_cast<ttmath_big>
+{
+ static inline ttmath_big apply(std::string const& source)
+ {
+ return ttmath_big(source);
+ }
+};
+
+} // namespace detail
+
+
+}} // boost::geometry
+
+
+
+
+// Support for boost::numeric_cast to int and to double (necessary for SVG-mapper)
+namespace boost { namespace numeric
+{
+
+template
+<
+ ttmath::uint Exponent, ttmath::uint Mantissa,
+ typename Traits,
+ typename OverflowHandler,
+ typename Float2IntRounder,
+ typename RawConverter,
+ typename UserRangeChecker
+>
+struct converter<int, ttmath::Big<Exponent, Mantissa>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
+{
+ static inline int convert(ttmath::Big<Exponent, Mantissa> arg)
+ {
+ int v;
+ arg.ToInt(v);
+ return v;
+ }
+};
+
+template
+<
+ ttmath::uint Exponent, ttmath::uint Mantissa,
+ typename Traits,
+ typename OverflowHandler,
+ typename Float2IntRounder,
+ typename RawConverter,
+ typename UserRangeChecker
+>
+struct converter<double, ttmath::Big<Exponent, Mantissa>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
+{
+ static inline double convert(ttmath::Big<Exponent, Mantissa> arg)
+ {
+ double v;
+ arg.ToDouble(v);
+ return v;
+ }
+};
+
+
+template
+<
+ typename Traits,
+ typename OverflowHandler,
+ typename Float2IntRounder,
+ typename RawConverter,
+ typename UserRangeChecker
+>
+struct converter<int, ttmath_big, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
+{
+ static inline int convert(ttmath_big arg)
+ {
+ int v;
+ arg.ToInt(v);
+ return v;
+ }
+};
+
+template
+<
+ typename Traits,
+ typename OverflowHandler,
+ typename Float2IntRounder,
+ typename RawConverter,
+ typename UserRangeChecker
+>
+struct converter<double, ttmath_big, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
+{
+ static inline double convert(ttmath_big arg)
+ {
+ double v;
+ arg.ToDouble(v);
+ return v;
+ }
+};
+
+
+}}
+
+
+#endif
diff --git a/src/boost/geometry/extensions/geometries/quantity_point.hpp b/src/boost/geometry/extensions/geometries/quantity_point.hpp
new file mode 100644
index 0000000..ebfd894
--- /dev/null
+++ b/src/boost/geometry/extensions/geometries/quantity_point.hpp
@@ -0,0 +1,134 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GEOMETRIES_QUANTITY_POINT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GEOMETRIES_QUANTITY_POINT_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/int.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/geometries/point.hpp>
+
+#include <boost/units/quantity.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace cs
+{
+
+template <typename Unit>
+struct units_cartesian {};
+
+}
+
+namespace traits
+{
+
+template<typename U>
+struct cs_tag<cs::units_cartesian<U> >
+{
+ typedef cartesian_tag type;
+};
+
+}
+
+
+namespace model
+{
+
+// Define a point type to interoperate with Boost.Units, having
+// 1. a constructor taking quantities
+// 2. defining a quantified coordinate system
+// Note that all values are still stored in "normal" types as double
+template
+<
+ typename Units,
+ std::size_t DimensionCount = 2,
+ typename CoordinateType = double,
+ typename CoordinateSystem = cs::units_cartesian<Units>
+>
+class quantity_point
+ : public model::point<CoordinateType, DimensionCount, CoordinateSystem>
+{
+ typedef boost::units::quantity<Units, CoordinateType> qtype;
+
+public :
+
+ // Templated constructor to allow constructing with other units then qtype,
+ // e.g. to convert from centimeters to meters
+ template <typename Quantity>
+ inline quantity_point(Quantity const& x, Quantity const& y)
+ : model::point<CoordinateType, DimensionCount, CoordinateSystem>(
+ qtype(x).value(),
+ qtype(y).value())
+ {}
+};
+
+}
+
+
+// Adapt quantity_point to the Point Concept
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename Units, std::size_t DimensionCount, typename CoordinateType, typename CoordinateSystem>
+struct tag<model::quantity_point<Units, DimensionCount, CoordinateType, CoordinateSystem> >
+{
+ typedef point_tag type;
+};
+
+template<typename Units, std::size_t DimensionCount, typename CoordinateType, typename CoordinateSystem>
+struct coordinate_type<model::quantity_point<Units, DimensionCount, CoordinateType, CoordinateSystem> >
+{
+ typedef CoordinateType type;
+};
+
+template<typename Units, std::size_t DimensionCount, typename CoordinateType, typename CoordinateSystem>
+struct coordinate_system<model::quantity_point<Units, DimensionCount, CoordinateType, CoordinateSystem> >
+{
+ typedef CoordinateSystem type;
+};
+
+template<typename Units, std::size_t DimensionCount, typename CoordinateType, typename CoordinateSystem>
+struct dimension<model::quantity_point<Units, DimensionCount, CoordinateType, CoordinateSystem> >
+ : boost::mpl::int_<DimensionCount>
+{};
+
+template<typename Units, std::size_t DimensionCount, typename CoordinateType, typename CoordinateSystem, std::size_t Dimension>
+struct access<model::quantity_point<Units, DimensionCount, CoordinateType, CoordinateSystem>, Dimension >
+{
+ static inline CoordinateType get(
+ model::quantity_point<Units, DimensionCount, CoordinateType, CoordinateSystem> const& p)
+ {
+ return p.template get<Dimension>();
+ }
+
+ static inline void set(model::quantity_point<Units, DimensionCount, CoordinateType, CoordinateSystem>& p,
+ CoordinateType const& value)
+ {
+ p.template set<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GEOMETRIES_QUANTITY_POINT_HPP
diff --git a/src/boost/geometry/extensions/gis/geographic/core/cs.hpp b/src/boost/geometry/extensions/gis/geographic/core/cs.hpp
new file mode 100644
index 0000000..878241e
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/geographic/core/cs.hpp
@@ -0,0 +1,81 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_CORE_CS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_CORE_CS_HPP
+
+
+
+namespace boost { namespace geometry
+{
+
+namespace cs
+{
+
+/*!
+ \brief EPSG Cartesian coordinate system
+ \details EPSG (European Petrol Survey Group) has a standard list of projections,
+ each having a code
+ \see
+ \ingroup cs
+ \tparam Code the EPSG code
+ \todo Maybe derive from boost::mpl::int_<EpsgCode>
+*/
+template<std::size_t Code>
+struct epsg
+{
+ static const std::size_t epsg_code = Code;
+};
+
+
+
+/*!
+ \brief Earth Centered, Earth Fixed
+ \details Defines a Cartesian coordinate system x,y,z with the center of the earth as its origin,
+ going through the Greenwich
+ \see http://en.wikipedia.org/wiki/ECEF
+ \see http://en.wikipedia.org/wiki/Geodetic_system
+ \note Also known as "Geocentric", but geocentric is also an astronomic coordinate system
+ \ingroup cs
+*/
+struct ecef
+{
+};
+
+
+} // namespace cs
+
+namespace traits
+{
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+template<>
+struct cs_tag<cs::ecef>
+{
+ typedef cartesian_tag type;
+};
+
+template <std::size_t C>
+struct cs_tag<cs::epsg<C> >
+{
+ typedef cartesian_tag type;
+};
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+} // namespace traits
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_CORE_CS_HPP
diff --git a/src/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp b/src/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp
new file mode 100644
index 0000000..b7b3c69
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp
@@ -0,0 +1,65 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP
+
+
+namespace boost { namespace geometry { namespace detail
+{
+
+
+/*!
+ \brief Defines ellipsoid values for use in distance calculations
+ \details They have a constructor with the earth radius
+ \note Will be moved / merged with projections
+ \todo Optionally specify earth model, defaulting to WGS84
+ - See http://en.wikipedia.org/wiki/Figure_of_the_Earth
+ - and http://en.wikipedia.org/wiki/World_Geodetic_System#A_new_World_Geodetic_System:_WGS84
+ \note
+*/
+template <typename T>
+class ellipsoid
+{
+ public :
+ ellipsoid(T const& a, T const& b)
+ : m_a(a)
+ , m_b(b)
+ , m_f((a - b) / a)
+ {}
+ ellipsoid()
+ : m_a(T(6378137.0))
+ , m_b(T(6356752.314245))
+ , m_f((m_a - m_b) / m_a)
+ {}
+ // Unit sphere
+ ellipsoid(T const& f)
+ : m_a(1.0)
+ , m_f(f)
+ {}
+
+ T a() const { return m_a; }
+ T b() const { return m_b; }
+ T f() const { return m_f; }
+
+ private :
+ T m_a, m_b, m_f; // equatorial radius, polar radius, flattening
+};
+
+
+
+
+}}} // namespace boost::geometry::detail
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP
diff --git a/src/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp b/src/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp
new file mode 100644
index 0000000..0834ba6
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp
@@ -0,0 +1,224 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_ANDOYER_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_ANDOYER_HPP
+
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+
+/*!
+\brief Point-point distance approximation taking flattening into account
+\ingroup distance
+\tparam Point1 \tparam_first_point
+\tparam Point2 \tparam_second_point
+\tparam CalculationType \tparam_calculation
+\author After Andoyer, 19xx, republished 1950, republished by Meeus, 1999
+\note Although not so well-known, the approximation is very good: in all cases the results
+are about the same as Vincenty. In my (Barend's) testcases the results didn't differ more than 6 m
+\see http://nacc.upc.es/tierra/node16.html
+\see http://sci.tech-archive.net/Archive/sci.geo.satellite-nav/2004-12/2724.html
+\see http://home.att.net/~srschmitt/great_circle_route.html (implementation)
+\see http://www.codeguru.com/Cpp/Cpp/algorithms/article.php/c5115 (implementation)
+\see http://futureboy.homeip.net/frinksamp/navigation.frink (implementation)
+\see http://www.voidware.com/earthdist.htm (implementation)
+*/
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
+class andoyer
+{
+ public :
+ typedef typename promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type
+ >::type calculation_type;
+
+ inline andoyer()
+ : m_ellipsoid()
+ {}
+
+ explicit inline andoyer(calculation_type f)
+ : m_ellipsoid(f)
+ {}
+
+ explicit inline andoyer(geometry::detail::ellipsoid<calculation_type> const& e)
+ : m_ellipsoid(e)
+ {}
+
+
+ inline calculation_type apply(Point1 const& point1, Point2 const& point2) const
+ {
+ return calc(get_as_radian<0>(point1), get_as_radian<1>(point1),
+ get_as_radian<0>(point2), get_as_radian<1>(point2));
+ }
+
+ inline geometry::detail::ellipsoid<calculation_type> ellipsoid() const
+ {
+ return m_ellipsoid;
+ }
+
+ inline calculation_type radius() const
+ {
+ return m_ellipsoid.a();
+ }
+
+
+ private :
+ geometry::detail::ellipsoid<calculation_type> m_ellipsoid;
+
+ inline calculation_type calc(calculation_type const& lon1,
+ calculation_type const& lat1,
+ calculation_type const& lon2,
+ calculation_type const& lat2) const
+ {
+ calculation_type const G = (lat1 - lat2) / 2.0;
+ calculation_type const lambda = (lon1 - lon2) / 2.0;
+
+ if (geometry::math::equals(lambda, 0.0)
+ && geometry::math::equals(G, 0.0))
+ {
+ return 0.0;
+ }
+
+ calculation_type const F = (lat1 + lat2) / 2.0;
+
+ calculation_type const sinG2 = math::sqr(sin(G));
+ calculation_type const cosG2 = math::sqr(cos(G));
+ calculation_type const sinF2 = math::sqr(sin(F));
+ calculation_type const cosF2 = math::sqr(cos(F));
+ calculation_type const sinL2 = math::sqr(sin(lambda));
+ calculation_type const cosL2 = math::sqr(cos(lambda));
+
+ calculation_type const S = sinG2 * cosL2 + cosF2 * sinL2;
+ calculation_type const C = cosG2 * cosL2 + sinF2 * sinL2;
+
+ calculation_type const c0 = 0;
+ calculation_type const c1 = 1;
+ calculation_type const c2 = 2;
+ calculation_type const c3 = 3;
+
+ if (geometry::math::equals(S, c0) || geometry::math::equals(C, c0))
+ {
+ return c0;
+ }
+
+ calculation_type const omega = atan(sqrt(S / C));
+ calculation_type const r3 = c3 * sqrt(S * C) / omega; // not sure if this is r or greek nu
+ calculation_type const D = c2 * omega * m_ellipsoid.a();
+ calculation_type const H1 = (r3 - c1) / (c2 * C);
+ calculation_type const H2 = (r3 + c1) / (c2 * S);
+ calculation_type const f = m_ellipsoid.f();
+
+ return D * (c1 + f * H1 * sinF2 * cosG2 - f * H2 * cosF2 * sinG2);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point1, typename Point2>
+struct tag<strategy::distance::andoyer<Point1, Point2> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Point1, typename Point2>
+struct return_type<strategy::distance::andoyer<Point1, Point2> >
+{
+ typedef typename strategy::distance::andoyer<Point1, Point2>::calculation_type type;
+};
+
+
+template <typename Point1, typename Point2, typename P1, typename P2>
+struct similar_type<andoyer<Point1, Point2>, P1, P2>
+{
+ typedef andoyer<P1, P2> type;
+};
+
+
+template <typename Point1, typename Point2, typename P1, typename P2>
+struct get_similar<andoyer<Point1, Point2>, P1, P2>
+{
+ static inline andoyer<P1, P2> apply(andoyer<Point1, Point2> const& input)
+ {
+ return andoyer<P1, P2>(input.ellipsoid());
+ }
+};
+
+template <typename Point1, typename Point2>
+struct comparable_type<andoyer<Point1, Point2> >
+{
+ typedef andoyer<Point1, Point2> type;
+};
+
+
+template <typename Point1, typename Point2>
+struct get_comparable<andoyer<Point1, Point2> >
+{
+ static inline andoyer<Point1, Point2> apply(andoyer<Point1, Point2> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename Point1, typename Point2>
+struct result_from_distance<andoyer<Point1, Point2> >
+{
+ template <typename T>
+ static inline typename return_type<andoyer<Point1, Point2> >::type apply(andoyer<Point1, Point2> const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+template <typename Point1, typename Point2>
+struct default_strategy<point_tag, Point1, Point2, geographic_tag, geographic_tag>
+{
+ typedef strategy::distance::andoyer<Point1, Point2> type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_ANDOYER_HPP
diff --git a/src/boost/geometry/extensions/gis/geographic/strategies/area_huiller_earth.hpp b/src/boost/geometry/extensions/gis/geographic/strategies/area_huiller_earth.hpp
new file mode 100644
index 0000000..8116279
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/geographic/strategies/area_huiller_earth.hpp
@@ -0,0 +1,64 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_AREA_HUILLER_EARTH_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_AREA_HUILLER_EARTH_HPP
+
+
+
+#include <boost/geometry/strategies/spherical/area_huiller.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace area
+{
+
+template
+<
+ typename PointOfSegment,
+ typename CalculationType = void
+>
+class huiller_earth
+ : public huiller<PointOfSegment, CalculationType>
+{
+public :
+ // By default the average earth radius.
+ // Uses can specify another radius.
+ // Note that the earth is still handled spherically
+ inline huiller_earth(double radius = 6372795.0)
+ : huiller<PointOfSegment, CalculationType>(radius)
+ {}
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+template <typename Point>
+struct default_strategy<geographic_tag, Point>
+{
+ typedef huiller_earth<Point> type;
+};
+
+} // namespace services
+
+
+#endif
+
+
+}} // namespace strategy::area
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_AREA_HUILLER_EARTH_HPP
diff --git a/src/boost/geometry/extensions/gis/geographic/strategies/distance_cross_track.hpp b/src/boost/geometry/extensions/gis/geographic/strategies/distance_cross_track.hpp
new file mode 100644
index 0000000..fbec0a5
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/geographic/strategies/distance_cross_track.hpp
@@ -0,0 +1,72 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+namespace services
+{
+
+
+template <typename Point, typename PointOfSegment, typename Strategy>
+struct default_strategy<segment_tag, Point, PointOfSegment, geographic_tag, geographic_tag, Strategy>
+{
+ typedef cross_track
+ <
+ Point,
+ PointOfSegment,
+ void,
+ typename boost::mpl::if_
+ <
+ boost::is_void<Strategy>,
+ typename default_strategy
+ <
+ point_tag, Point, PointOfSegment,
+ geographic_tag, geographic_tag
+ >::type,
+ Strategy
+ >::type
+ > type;
+};
+
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_GEOGRAPHIC_DISTANCE_CROSS_TRACK_HPP
diff --git a/src/boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp b/src/boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp
new file mode 100644
index 0000000..5db5fcb
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp
@@ -0,0 +1,267 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_DMS_PARSER_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_DMS_PARSER_HPP
+
+// This file is totally revised from PROJ4 dmstor.c
+
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <string>
+
+#include <boost/static_assert.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/extensions/strategies/parse.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+struct dms_result
+{
+ enum axis_selector {axis_lat = 1, axis_lon = 0};
+
+ private :
+ typedef double T;
+ T m_angle;
+ axis_selector m_axis;
+
+ public :
+
+ explicit dms_result(T const& v, axis_selector ax)
+ : m_angle(v)
+ , m_axis(ax)
+ {}
+
+ inline axis_selector axis() const { return m_axis; }
+
+ inline operator double() const { return m_angle; }
+
+ template <typename CH, typename TR>
+ inline friend std::basic_ostream<CH, TR>& operator<<(std::basic_ostream<CH, TR>& os,
+ const dms_result& d)
+ {
+ os << d.m_angle;
+ return os;
+ }
+
+};
+
+
+namespace strategy
+{
+
+ template <bool as_radian = true
+ , char N = 'N', char E = 'E', char S = 'S', char W = 'W' // translatable
+ , char MIN = '\'', char SEC = '"' // other char's possible
+ , char D = 'D', char R = 'R' // degree sign might be small o
+ >
+ struct dms_parser
+ {
+
+
+ // Question from Barend: can we compile-time select that it is case-sensitive/case-insensitive?
+ // We have to change the switch then -> specializations
+
+ // For now: make it (compile-time) case sensitive
+ static const int diff = 'a' - 'A';
+#ifndef __GNUC__
+ BOOST_STATIC_ASSERT((diff > 0)); // make sure we've the right assumption. GCC does not accept this here.
+#endif
+ static const char n_alter = N <= 'Z' ? N + diff : N - diff;
+ static const char e_alter = E <= 'Z' ? E + diff : E - diff;
+ static const char s_alter = S <= 'Z' ? S + diff : S - diff;
+ static const char w_alter = W <= 'Z' ? W + diff : W - diff;
+
+ static const char r_alter = R <= 'Z' ? R + diff : R - diff;
+
+ // degree is normally D (proj4) but might be superscript o
+ // Note d_alter is not correct then, so map it to NULL now, guarded by the while
+ static const char d_alter =
+ ((D >= 'A' && D <= 'Z') || (D >= 'a' && D <= 'z')) ? (D <= 'Z' ? D + diff : D - diff) : '\0';
+
+
+ struct dms_value
+ {
+ double dms[3];
+ bool has_dms[3];
+
+ dms_value()
+ {
+ memset(this, 0, sizeof(dms_value));
+ }
+ };
+
+
+ template <size_t I>
+ static inline void assign_dms(dms_value& dms, std::string& value, bool& has_value)
+ {
+ dms.dms[I] = boost::lexical_cast<double>(value.c_str());
+ dms.has_dms[I] = true;
+ has_value = false;
+ value.clear();
+ }
+
+ static inline void process(dms_value& dms, std::string& value, bool& has_value)
+ {
+ if (has_value)
+ {
+ // Assign last one, sequentially
+ if (! dms.has_dms[0]) assign_dms<0>(dms, value, has_value);
+ else if (! dms.has_dms[1]) assign_dms<1>(dms, value, has_value);
+ else if (! dms.has_dms[2]) assign_dms<2>(dms, value, has_value);
+ }
+ }
+
+
+ dms_result operator()(const char* is) const
+ {
+ dms_value dms;
+ bool has_value = false;
+ std::string value;
+
+ double factor = 1.0; // + denotes N/E values, -1 denotes S/W values
+ dms_result::axis_selector axis = dms_result::axis_lon; // true denotes N/S values
+ bool in_radian = false; // true denotes values as "0.1R"
+
+ while(*is)
+ {
+ switch(*is)
+ {
+ case '-' :
+ if (! has_value && ! dms.has_dms[0])
+ {
+ factor = -factor;
+ }
+ break;
+ case N :
+ case n_alter :
+ axis = dms_result::axis_lat;
+ break;
+ case S :
+ case s_alter :
+ axis = dms_result::axis_lat;
+ factor = -factor;
+ break;
+ case E :
+ case e_alter :
+ axis = dms_result::axis_lon;
+ break;
+ case W :
+ case w_alter :
+ axis = dms_result::axis_lon;
+ factor = -factor;
+ break;
+ case D :
+ case d_alter :
+ if (! dms.has_dms[0] && has_value)
+ {
+ assign_dms<0>(dms, value, has_value);
+ }
+ break;
+ case R :
+ case r_alter :
+ if (! dms.has_dms[0] && has_value)
+ {
+ // specified value is in radian!
+ in_radian = true;
+ assign_dms<0>(dms, value, has_value);
+ }
+ break;
+ case MIN:
+ if (! dms.has_dms[1] && has_value)
+ {
+ assign_dms<1>(dms, value, has_value);
+ }
+ break;
+ case SEC :
+ if (! dms.has_dms[2] && has_value)
+ {
+ assign_dms<2>(dms, value, has_value);
+ }
+ break;
+ case ' ' :
+ case '\t' :
+ case '\n' :
+ process(dms, value, has_value);
+ break;
+ default :
+ value += *is;
+ has_value = true;
+ break;
+ }
+ is++;
+ }
+
+ // Assign last one, if any
+ process(dms, value, has_value);
+
+ return dms_result(factor *
+ (in_radian && as_radian
+ ? dms.dms[0]
+ : in_radian && ! as_radian
+ ? dms.dms[0] * math::r2d
+ : ! in_radian && as_radian
+ ? dms.dms[0] * math::d2r + dms.dms[1] * math::d2r / 60.0 + dms.dms[2] * math::d2r / 3600.0
+ : dms.dms[0] + dms.dms[1] / 60.0 + dms.dms[2] / 3600.0)
+ , axis);
+ }
+ };
+
+}
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+template <template<typename> class CS>
+struct strategy_parse<geographic_tag, CS<degree> >
+{
+ typedef strategy::dms_parser<false> type;
+};
+
+
+template <template<typename> class CS>
+struct strategy_parse<geographic_tag, CS<radian> >
+{
+ typedef strategy::dms_parser<true> type;
+};
+
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_DMS_PARSER_HPP
diff --git a/src/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp b/src/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp
new file mode 100644
index 0000000..9b9b887
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp
@@ -0,0 +1,262 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP
+
+#include <boost/math/constants/constants.hpp>
+
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp>
+
+
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+/*!
+\brief Distance calculation formulae on latlong coordinates, after Vincenty, 1975
+\ingroup distance
+\tparam Point1 \tparam_first_point
+\tparam Point2 \tparam_second_point
+\tparam CalculationType \tparam_calculation
+\author See http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+\author Adapted from various implementations to get it close to the original document
+ - http://www.movable-type.co.uk/scripts/LatLongVincenty.html
+ - http://exogen.case.edu/projects/geopy/source/geopy.distance.html
+ - http://futureboy.homeip.net/fsp/colorize.fsp?fileName=navigation.frink
+
+*/
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
+class vincenty
+{
+public :
+ typedef typename promote_floating_point
+ <
+ typename select_most_precise
+ <
+ typename select_calculation_type
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type,
+ double // to avoid bad results in float
+ >::type
+ >::type calculation_type;
+
+ inline vincenty()
+ {}
+
+ explicit inline vincenty(geometry::detail::ellipsoid<calculation_type> const& e)
+ : m_ellipsoid(e)
+ {}
+
+ inline calculation_type apply(Point1 const& p1, Point2 const& p2) const
+ {
+ return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
+ get_as_radian<0>(p2), get_as_radian<1>(p2));
+ }
+
+ inline geometry::detail::ellipsoid<calculation_type> ellipsoid() const
+ {
+ return m_ellipsoid;
+ }
+
+
+private :
+ geometry::detail::ellipsoid<calculation_type> m_ellipsoid;
+
+ inline calculation_type calculate(calculation_type const& lon1,
+ calculation_type const& lat1,
+ calculation_type const& lon2,
+ calculation_type const& lat2) const
+ {
+ calculation_type const c2 = 2;
+ calculation_type const pi = geometry::math::pi<calculation_type>();
+ calculation_type const two_pi = c2 * pi;
+
+ // lambda: difference in longitude on an auxiliary sphere
+ calculation_type L = lon2 - lon1;
+ calculation_type lambda = L;
+
+ if (L < -pi) L += two_pi;
+ if (L > pi) L -= two_pi;
+
+ if (math::equals(lat1, lat2) && math::equals(lon1, lon2))
+ {
+ return calculation_type(0);
+ }
+
+ // U: reduced latitude, defined by tan U = (1-f) tan phi
+ calculation_type const c1 = 1;
+ calculation_type const one_min_f = c1 - m_ellipsoid.f();
+
+ calculation_type const U1 = atan(one_min_f * tan(lat1)); // above (1)
+ calculation_type const U2 = atan(one_min_f * tan(lat2)); // above (1)
+
+ calculation_type const cos_U1 = cos(U1);
+ calculation_type const cos_U2 = cos(U2);
+ calculation_type const sin_U1 = sin(U1);
+ calculation_type const sin_U2 = sin(U2);
+
+ // alpha: azimuth of the geodesic at the equator
+ calculation_type cos2_alpha;
+ calculation_type sin_alpha;
+
+ // sigma: angular distance p1,p2 on the sphere
+ // sigma1: angular distance on the sphere from the equator to p1
+ // sigma_m: angular distance on the sphere from the equator to the midpoint of the line
+ calculation_type sigma;
+ calculation_type sin_sigma;
+ calculation_type cos2_sigma_m;
+
+ calculation_type previous_lambda;
+
+ calculation_type const c3 = 3;
+ calculation_type const c4 = 4;
+ calculation_type const c6 = 6;
+ calculation_type const c16 = 16;
+
+ calculation_type const c_e_12 = 1e-12;
+
+ do
+ {
+ previous_lambda = lambda; // (13)
+ calculation_type sin_lambda = sin(lambda);
+ calculation_type cos_lambda = cos(lambda);
+ sin_sigma = sqrt(math::sqr(cos_U2 * sin_lambda) + math::sqr(cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda)); // (14)
+ calculation_type cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda; // (15)
+ sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma; // (17)
+ cos2_alpha = c1 - math::sqr(sin_alpha);
+ cos2_sigma_m = math::equals(cos2_alpha, 0) ? 0 : cos_sigma - c2 * sin_U1 * sin_U2 / cos2_alpha; // (18)
+
+ calculation_type C = m_ellipsoid.f()/c16 * cos2_alpha * (c4 + m_ellipsoid.f() * (c4 - c3 * cos2_alpha)); // (10)
+ sigma = atan2(sin_sigma, cos_sigma); // (16)
+ lambda = L + (c1 - C) * m_ellipsoid.f() * sin_alpha *
+ (sigma + C * sin_sigma * ( cos2_sigma_m + C * cos_sigma * (-c1 + c2 * math::sqr(cos2_sigma_m)))); // (11)
+
+ } while (geometry::math::abs(previous_lambda - lambda) > c_e_12
+ && geometry::math::abs(lambda) < pi);
+
+ calculation_type sqr_u = cos2_alpha * (math::sqr(m_ellipsoid.a()) - math::sqr(m_ellipsoid.b())) / math::sqr(m_ellipsoid.b()); // above (1)
+
+ // Oops getting hard here
+ // (again, problem is that ttmath cannot divide by doubles, which is OK)
+ calculation_type const c47 = 47;
+ calculation_type const c74 = 74;
+ calculation_type const c128 = 128;
+ calculation_type const c256 = 256;
+ calculation_type const c175 = 175;
+ calculation_type const c320 = 320;
+ calculation_type const c768 = 768;
+ calculation_type const c1024 = 1024;
+ calculation_type const c4096 = 4096;
+ calculation_type const c16384 = 16384;
+
+ calculation_type A = c1 + sqr_u/c16384 * (c4096 + sqr_u * (-c768 + sqr_u * (c320 - c175 * sqr_u))); // (3)
+ calculation_type B = sqr_u/c1024 * (c256 + sqr_u * ( -c128 + sqr_u * (c74 - c47 * sqr_u))); // (4)
+ calculation_type delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/c4) * (cos(sigma)* (-c1 + c2 * cos2_sigma_m)
+ - (B/c6) * cos2_sigma_m * (-c3 + c4 * math::sqr(sin_sigma)) * (-c3 + c4 * cos2_sigma_m))); // (6)
+
+ return m_ellipsoid.b() * A * (sigma - delta_sigma); // (19)
+ }
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point1, typename Point2>
+struct tag<strategy::distance::vincenty<Point1, Point2> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Point1, typename Point2>
+struct return_type<strategy::distance::vincenty<Point1, Point2> >
+{
+ typedef typename strategy::distance::vincenty<Point1, Point2>::calculation_type type;
+};
+
+
+template <typename Point1, typename Point2, typename P1, typename P2>
+struct similar_type<vincenty<Point1, Point2>, P1, P2>
+{
+ typedef vincenty<P1, P2> type;
+};
+
+
+template <typename Point1, typename Point2, typename P1, typename P2>
+struct get_similar<vincenty<Point1, Point2>, P1, P2>
+{
+ static inline vincenty<P1, P2> apply(vincenty<Point1, Point2> const& input)
+ {
+ return vincenty<P1, P2>(input.ellipsoid());
+ }
+};
+
+template <typename Point1, typename Point2>
+struct comparable_type<vincenty<Point1, Point2> >
+{
+ typedef vincenty<Point1, Point2> type;
+};
+
+
+template <typename Point1, typename Point2>
+struct get_comparable<vincenty<Point1, Point2> >
+{
+ static inline vincenty<Point1, Point2> apply(vincenty<Point1, Point2> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename Point1, typename Point2>
+struct result_from_distance<vincenty<Point1, Point2> >
+{
+ template <typename T>
+ static inline typename return_type<vincenty<Point1, Point2> >::type apply(vincenty<Point1, Point2> const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+// We might add a vincenty-like strategy also for point-segment distance, but to calculate the projected point is not trivial
+
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP
diff --git a/src/boost/geometry/extensions/gis/io/shapelib/dbf_write_attribute.hpp b/src/boost/geometry/extensions/gis/io/shapelib/dbf_write_attribute.hpp
new file mode 100644
index 0000000..4ed21de
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/shapelib/dbf_write_attribute.hpp
@@ -0,0 +1,87 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_DBF_WRITE_ATTRIBUTE_HPP
+#define BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_DBF_WRITE_ATTRIBUTE_HPP
+
+
+
+
+// Should be somewhere in your include path
+#include "shapefil.h"
+
+
+
+namespace boost { namespace geometry
+{
+
+namespace detail
+{
+
+// Called with promote so not all cases necessary
+template <typename T> struct DBFFieldType {};
+template <> struct DBFFieldType<int> { static ::DBFFieldType const value = FTInteger; };
+template <> struct DBFFieldType<double> { static ::DBFFieldType const value = FTDouble; };
+template <> struct DBFFieldType<std::string> { static ::DBFFieldType const value = FTString; };
+
+// Also called with promote
+template <typename T> struct DBFWriteAttribute
+{
+};
+
+template <> struct DBFWriteAttribute<int>
+{
+ template <typename T>
+ inline static void apply(DBFHandle dbf, int row_index, int field_index,
+ T const& value)
+ {
+ DBFWriteIntegerAttribute(dbf, row_index, field_index, value);
+ }
+};
+
+template <> struct DBFWriteAttribute<double>
+{
+ template <typename T>
+ inline static void apply(DBFHandle dbf, int row_index, int field_index,
+ T const& value)
+ {
+ DBFWriteDoubleAttribute(dbf, row_index, field_index, value);
+ }
+};
+
+template <> struct DBFWriteAttribute<std::string>
+{
+ inline static void apply(DBFHandle dbf, int row_index, int field_index,
+ std::string const& value)
+ {
+ DBFWriteStringAttribute(dbf, row_index, field_index, value.c_str());
+ }
+};
+
+// Derive char* variants from std::string,
+// implicitly casting to a temporary std::string
+// (note that boost::remove_const does not remove const from "const char*")
+template <int N>
+struct DBFWriteAttribute<char[N]> : DBFWriteAttribute<std::string> {};
+
+template <int N>
+struct DBFWriteAttribute<const char[N]> : DBFWriteAttribute<std::string> {};
+
+template <>
+struct DBFWriteAttribute<const char*> : DBFWriteAttribute<std::string> {};
+
+template <>
+struct DBFWriteAttribute<char*> : DBFWriteAttribute<std::string> {};
+
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_DBF_WRITE_ATTRIBUTE_HPP
diff --git a/src/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp b/src/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp
new file mode 100644
index 0000000..74aa5fc
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp
@@ -0,0 +1,155 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHAPE_CREATOR_HPP
+#define BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHAPE_CREATOR_HPP
+
+#include <fstream>
+#include "shapefil.h"
+
+#include <boost/noncopyable.hpp>
+#include <boost/type_traits/promote.hpp>
+
+#include <boost/geometry/io/wkt/wkt.hpp>
+
+#include <boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp>
+#include <boost/geometry/extensions/gis/io/shapelib/shp_create_object_multi.hpp>
+#include <boost/geometry/extensions/gis/io/shapelib/dbf_write_attribute.hpp>
+
+namespace boost { namespace geometry
+{
+
+class shapelib_file_create_exception : public geometry::exception
+{
+public:
+
+ inline shapelib_file_create_exception(std::string const& filename)
+ : m_filename(filename)
+ {}
+
+ virtual char const* what() const throw()
+ {
+ return m_filename.c_str();
+ }
+ virtual ~shapelib_file_create_exception() throw() { }
+private :
+ std::string m_filename;
+};
+
+namespace detail
+{
+
+template <typename Tag>
+struct SHPType
+{
+};
+
+template <> struct SHPType<point_tag> { static int const value = SHPT_POINT; };
+template <> struct SHPType<segment_tag> { static int const value = SHPT_ARC; };
+template <> struct SHPType<linestring_tag> { static int const value = SHPT_ARC; };
+template <> struct SHPType<polygon_tag> { static int const value = SHPT_POLYGON; };
+template <> struct SHPType<ring_tag> { static int const value = SHPT_POLYGON; };
+template <> struct SHPType<box_tag> { static int const value = SHPT_POLYGON; };
+
+template <> struct SHPType<multi_point_tag> { static int const value = SHPT_MULTIPOINT; };
+template <> struct SHPType<multi_linestring_tag> { static int const value = SHPT_ARC; };
+template <> struct SHPType<multi_polygon_tag> { static int const value = SHPT_POLYGON; };
+
+} // namespace detail
+
+template
+<
+ typename Geometry,
+ int ShapeType = detail::SHPType
+ <
+ typename geometry::tag<Geometry>::type
+ >::value
+>
+class shape_creator : public boost::noncopyable
+{
+public :
+ shape_creator(std::string const& name)
+ {
+ m_shp = ::SHPCreate((name + ".shp").c_str(), ShapeType);
+ m_dbf = ::DBFCreate((name + ".dbf").c_str());
+ m_prj_name = name + ".prj";
+
+ if (m_shp == NULL || m_dbf == NULL)
+ {
+ throw shapelib_file_create_exception(name);
+ }
+ }
+
+ virtual ~shape_creator()
+ {
+ if (m_shp) ::SHPClose(m_shp);
+ if (m_dbf) ::DBFClose(m_dbf);
+ }
+
+ // Returns: index in shapefile
+ inline int AddShape(Geometry const& geometry)
+ {
+ // Note: we MIGHT design a small wrapper class which destroys in destructor
+ ::SHPObject* obj = SHPCreateObject(geometry);
+ int result = SHPWriteObject(m_shp, -1, obj );
+ ::SHPDestroyObject( obj );
+ return result;
+ }
+
+ template <typename T>
+ inline void AddField(std::string const& name, int width = 16, int decimals = 0)
+ {
+ ::DBFAddField(m_dbf, name.c_str(),
+ detail::DBFFieldType
+ <
+ typename boost::promote<T>::type
+ >::value,
+ width, decimals);
+ }
+
+ template <typename T>
+ inline void WriteField(int row_index, int field_index, T const& value)
+ {
+ detail::DBFWriteAttribute
+ <
+ typename boost::promote<T>::type
+ >::apply(m_dbf, row_index, field_index, value);
+ }
+
+ inline void SetSrid(int srid)
+ {
+ if (srid == 28992)
+ {
+ std::ofstream out(m_prj_name.c_str());
+ out << "PROJCS[\"RD_New\""
+ << ",GEOGCS[\"GCS_Amersfoort\""
+ << ",DATUM[\"D_Amersfoort\""
+ << ",SPHEROID[\"Bessel_1841\",6377397.155,299.1528128]]"
+ << ",PRIMEM[\"Greenwich\",0]"
+ << ",UNIT[\"Degree\",0.0174532925199432955]]"
+ << ",PROJECTION[\"Double_Stereographic\"]"
+ << ",PARAMETER[\"False_Easting\",155000]"
+ << ",PARAMETER[\"False_Northing\",463000]"
+ << ",PARAMETER[\"Central_Meridian\",5.38763888888889]"
+ << ",PARAMETER[\"Scale_Factor\",0.9999079]"
+ << ",PARAMETER[\"Latitude_Of_Origin\",52.15616055555555]"
+ << ",UNIT[\"Meter\",1]]"
+ << std::endl;
+ }
+ }
+
+private :
+ ::SHPHandle m_shp;
+ ::DBFHandle m_dbf;
+ std::string m_prj_name;
+
+};
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHAPE_CREATOR_HPP
diff --git a/src/boost/geometry/extensions/gis/io/shapelib/shape_reader.hpp b/src/boost/geometry/extensions/gis/io/shapelib/shape_reader.hpp
new file mode 100644
index 0000000..4c1ca7b
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/shapelib/shape_reader.hpp
@@ -0,0 +1,72 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHAPE_READER_HPP
+#define BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHAPE_READER_HPP
+
+#include <fstream>
+#include "shapefil.h"
+
+
+#include <boost/noncopyable.hpp>
+#include <boost/type_traits/promote.hpp>
+
+#include <boost/geometry/extensions/gis/io/shapelib/shp_read_object.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+namespace detail
+{
+
+
+template<typename Geometry>
+class shape_reader : public boost::noncopyable
+{
+public :
+ shape_reader(std::string const& name)
+ {
+ m_shp = ::SHPOpen((name + ".shp").c_str(), "rb");
+ m_dbf = ::DBFOpen((name + ".dbf").c_str(), "rb");
+
+ if (m_shp == NULL || m_dbf == NULL)
+ {
+ throw shapelib_file_open_exception(name);
+ }
+
+ double adfMinBound[4], adfMaxBound[4];
+ SHPGetInfo(m_shp, &m_count, &m_shape_type, adfMinBound, adfMaxBound );
+
+ }
+ virtual ~shape_reader()
+ {
+ if (m_shp) ::SHPClose(m_shp);
+ if (m_dbf) ::DBFClose(m_dbf);
+ }
+
+ inline int count() const { return m_count; }
+
+
+
+
+private :
+ ::SHPHandle m_shp;
+ ::DBFHandle m_dbf;
+ int m_count;
+ int m_shape_type;
+
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHAPE_READER_HPP
diff --git a/src/boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp b/src/boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp
new file mode 100644
index 0000000..2e88de0
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp
@@ -0,0 +1,227 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_CREATE_OBJECT_HPP
+#define BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_CREATE_OBJECT_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/views/box_view.hpp>
+#include <boost/geometry/views/segment_view.hpp>
+
+
+// Should be somewhere in your include path
+#include "shapefil.h"
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace shp_create_object
+{
+
+template <typename Point>
+struct shape_create_point
+{
+
+ static inline SHPObject* apply(Point const& point)
+ {
+ double x = get<0>(point);
+ double y = get<1>(point);
+
+ int const parts = 0;
+
+ return ::SHPCreateObject(SHPT_POINT, -1, 1, &parts, NULL,
+ 1, &x, &y, NULL, NULL);
+ }
+};
+
+
+template <typename Range>
+static inline int range_to_part(Range const& range, double* x, double* y, int offset = 0)
+{
+ x += offset;
+ y += offset;
+
+ for (typename boost::range_iterator<Range const>::type
+ it = boost::begin(range);
+ it != boost::end(range);
+ ++it, ++x, ++y)
+ {
+ *x = get<0>(*it);
+ *y = get<1>(*it);
+ offset++;
+ }
+ return offset;
+}
+
+
+template <typename Range, int ShapeType>
+struct shape_create_range
+{
+ static inline SHPObject* apply(Range const& range)
+ {
+ int const n = boost::size(range);
+
+ boost::scoped_array<double> x(new double[n]);
+ boost::scoped_array<double> y(new double[n]);
+
+ range_to_part(range, x.get(), y.get());
+
+ int const parts = 0;
+
+ return ::SHPCreateObject(ShapeType, -1, 1, &parts, NULL,
+ n, x.get(), y.get(), NULL, NULL);
+ }
+};
+
+
+template <typename Polygon>
+struct shape_create_polygon
+{
+ static inline void process_polygon(Polygon const& polygon,
+ double* xp, double* yp, int* parts,
+ int& offset, int& ring)
+ {
+ parts[ring++] = offset;
+ offset = range_to_part(geometry::exterior_ring(polygon), xp, yp, offset);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ parts[ring++] = offset;
+ offset = range_to_part(*it, xp, yp, offset);
+ }
+ }
+
+ static inline SHPObject* apply(Polygon const& polygon)
+ {
+ int const n = geometry::num_points(polygon);
+ int const ring_count = 1 + geometry::num_interior_rings(polygon);
+
+ boost::scoped_array<double> x(new double[n]);
+ boost::scoped_array<double> y(new double[n]);
+ boost::scoped_array<int> parts(new int[ring_count]);
+
+ int ring = 0;
+ int offset = 0;
+
+ process_polygon(polygon, x.get(), y.get(), parts.get(), offset, ring);
+
+ return ::SHPCreateObject(SHPT_POLYGON, -1, ring_count, parts.get(), NULL,
+ n, x.get(), y.get(), NULL, NULL);
+ }
+};
+
+template <typename Geometry, typename AdaptedRange, int ShapeType>
+struct shape_create_adapted_range
+{
+ static inline SHPObject* apply(Geometry const& geometry)
+ {
+ return shape_create_range<AdaptedRange, ShapeType>::apply(AdaptedRange(geometry));
+ }
+};
+
+
+
+}} // namespace detail::shp_create_object
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Tag, typename Geometry>
+struct shp_create_object
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (Geometry)
+ );
+};
+
+
+template <typename Point>
+struct shp_create_object<point_tag, Point>
+ : detail::shp_create_object::shape_create_point<Point>
+{};
+
+
+template <typename LineString>
+struct shp_create_object<linestring_tag, LineString>
+ : detail::shp_create_object::shape_create_range<LineString, SHPT_ARC>
+{};
+
+
+template <typename Ring>
+struct shp_create_object<ring_tag, Ring>
+ : detail::shp_create_object::shape_create_range<Ring, SHPT_POLYGON>
+{};
+
+
+template <typename Polygon>
+struct shp_create_object<polygon_tag, Polygon>
+ : detail::shp_create_object::shape_create_polygon<Polygon>
+{};
+
+template <typename Box>
+struct shp_create_object<box_tag, Box>
+ : detail::shp_create_object::shape_create_adapted_range
+ <
+ Box,
+ box_view<Box>,
+ SHPT_POLYGON
+ >
+{};
+
+template <typename Segment>
+struct shp_create_object<segment_tag, Segment>
+ : detail::shp_create_object::shape_create_adapted_range
+ <
+ Segment,
+ segment_view<Segment>,
+ SHPT_ARC
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+// Redirect shapelib's SHPCreateObject to this boost::geometry::SHPCreateObject.
+// The only difference is their parameters, one just accepts a geometry
+template <typename Geometry>
+inline SHPObject* SHPCreateObject(Geometry const& geometry)
+{
+ return dispatch::shp_create_object
+ <
+ typename tag<Geometry>::type, Geometry
+ >::apply(geometry);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_CREATE_OBJECT_HPP
diff --git a/src/boost/geometry/extensions/gis/io/shapelib/shp_create_object_multi.hpp b/src/boost/geometry/extensions/gis/io/shapelib/shp_create_object_multi.hpp
new file mode 100644
index 0000000..9dd911f
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/shapelib/shp_create_object_multi.hpp
@@ -0,0 +1,147 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_CREATE_OBJECT_MULTI_HPP
+#define BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_CREATE_OBJECT_MULTI_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/scoped_array.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+#include <boost/geometry/multi/algorithms/num_interior_rings.hpp>
+
+#include <boost/geometry/extensions/gis/io/shapelib/shp_create_object.hpp>
+
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace shp_create_object
+{
+
+
+template <typename MultiPoint>
+struct shape_create_multi_point
+{
+ static inline SHPObject* apply(MultiPoint const& multi)
+ {
+ int const n = boost::size(multi);
+ boost::scoped_array<double> x(new double[n]);
+ boost::scoped_array<double> y(new double[n]);
+
+ range_to_part(multi, x.get(), y.get());
+
+ int const parts = 0;
+ return ::SHPCreateObject(SHPT_MULTIPOINT, -1, 1, &parts, NULL,
+ n, x.get(), y.get(), NULL, NULL);
+ }
+};
+
+
+
+template <typename MultiLinestring>
+struct shape_create_multi_linestring
+{
+ static inline SHPObject* apply(MultiLinestring const& multi)
+ {
+ int const n = geometry::num_points(multi);
+ int const part_count = boost::size(multi);
+
+ boost::scoped_array<double> x(new double[n]);
+ boost::scoped_array<double> y(new double[n]);
+ boost::scoped_array<int> parts(new int[part_count]);
+
+ int ring = 0;
+ int offset = 0;
+
+ for (typename boost::range_iterator<MultiLinestring const>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ parts[ring++] = offset;
+ offset = range_to_part(*it, x.get(), y.get(), offset);
+ }
+
+ return ::SHPCreateObject(SHPT_ARC, -1, part_count, parts.get(), NULL,
+ n, x.get(), y.get(), NULL, NULL);
+ }
+};
+
+
+template <typename MultiPolygon>
+struct shape_create_multi_polygon
+{
+ static inline SHPObject* apply(MultiPolygon const& multi)
+ {
+ int const n = geometry::num_points(multi);
+ int const ring_count = boost::size(multi) + geometry::num_interior_rings(multi);
+
+ boost::scoped_array<double> x(new double[n]);
+ boost::scoped_array<double> y(new double[n]);
+ boost::scoped_array<int> parts(new int[ring_count]);
+
+ int ring = 0;
+ int offset = 0;
+
+ typedef typename boost::range_value<MultiPolygon>::type polygon_type;
+ for (typename boost::range_iterator<MultiPolygon const>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ shape_create_polygon<polygon_type>::process_polygon(*it, x.get(), y.get(), parts.get(),
+ offset, ring);
+ }
+
+ return ::SHPCreateObject(SHPT_POLYGON, -1, ring_count, parts.get(), NULL,
+ n, x.get(), y.get(), NULL, NULL);
+ }
+};
+
+
+}} // namespace detail::shp_create_object
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiPoint>
+struct shp_create_object<multi_point_tag, MultiPoint>
+ : detail::shp_create_object::shape_create_multi_point<MultiPoint>
+{};
+
+
+template <typename MultiLinestring>
+struct shp_create_object<multi_linestring_tag, MultiLinestring>
+ : detail::shp_create_object::shape_create_multi_linestring<MultiLinestring>
+{};
+
+
+template <typename MultiPolygon>
+struct shp_create_object<multi_polygon_tag, MultiPolygon>
+ : detail::shp_create_object::shape_create_multi_polygon<MultiPolygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_CREATE_OBJECT_MULTI_HPP
diff --git a/src/boost/geometry/extensions/gis/io/shapelib/shp_read_object.hpp b/src/boost/geometry/extensions/gis/io/shapelib/shp_read_object.hpp
new file mode 100644
index 0000000..73204a9
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/shapelib/shp_read_object.hpp
@@ -0,0 +1,225 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_READ_OBJECT_HPP
+#define BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_READ_OBJECT_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/scoped_array.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+
+
+// Should be somewhere in your include path
+#include "shapefil.h"
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace shp_read_object
+{
+
+
+template <typename Pair>
+struct sort_on_area_desc
+{
+ inline bool operator()(Pair const& left, Pair const& right)
+ {
+ return left.second > right.second;
+ }
+};
+
+
+
+template <typename LineString>
+struct read_linestring
+{
+ static inline SHPObject* apply(LineString const& linestring)
+ {
+ typedef typename geometry::point_type<Linestring>::type point_type;
+
+ if (shape.nSHPType == SHPT_ARCZ && shape.nParts == 1)
+ {
+ double* const x = shape.padfX;
+ double* const y = shape.padfY;
+
+ for (int i = 0; i < shape.nVertices; i++)
+ {
+ point_type point;
+ geometry::set<0>(point, x[i]);
+ geometry::set<1>(point, y[i]);
+
+ linestring.push_back(point);
+ }
+ return true;
+ }
+ return false;
+
+ }
+};
+
+
+template <typename Polygon>
+struct read_polygon
+{
+ static inline SHPObject* apply(Polygon const& polygon)
+ {
+ typedef typename geometry::point_type<Polygon>::type point_type;
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+
+ if (shape.nSHPType == SHPT_POLYGON)
+ {
+ //std::cout << shape.nParts << " " << shape.nVertices << std::endl;
+
+ double* const x = shape.padfX;
+ double* const y = shape.padfY;
+
+ typedef std::pair<ring_type, double> ring_plus_area;
+ std::vector<ring_plus_area> rings;
+ rings.resize(shape.nParts);
+
+ int v = 0;
+ for (int p = 0; p < shape.nParts; p++)
+ {
+ int const first = shape.panPartStart[p];
+ int const last = p + 1 < shape.nParts
+ ? shape.panPartStart[p + 1]
+ : shape.nVertices;
+
+ for (v = first; v < last; v++)
+ {
+ point_type point;
+ geometry::set<0>(point, x[v]);
+ geometry::set<1>(point, y[v]);
+ rings[p].first.push_back(point);
+ }
+ rings[p].second = geometry::math::abs(geometry::area(rings[p].first));
+ }
+
+ if (rings.size() > 1)
+ {
+ // Sort rings on area
+ std::sort(rings.begin(), rings.end(),
+ sort_on_area_desc<ring_plus_area>());
+ // Largest area (either positive or negative) is outer ring
+ // Rest of the rings are holes
+ geometry::exterior_ring(polygon) = rings.front().first;
+ for (int i = 1; i < rings.size(); i++)
+ {
+ geometry::interior_rings(polygon).push_back(rings[i].first);
+ if (! geometry::within(rings[i].first.front(), geometry::exterior_ring(polygon))
+ && ! geometry::within(rings[i].first.at(1), geometry::exterior_ring(polygon))
+ )
+ {
+ #if ! defined(NDEBUG)
+ std::cout << "Error: inconsistent ring!" << std::endl;
+ BOOST_FOREACH(ring_plus_area const& r, rings)
+ {
+ std::cout << geometry::area(r.first) << " "
+ << geometry::wkt(r.first.front()) << " "
+ << std::endl;
+ }
+ #endif
+ }
+ }
+ }
+ else if (rings.size() == 1)
+ {
+ geometry::exterior_ring(polygon) = rings.front().first;
+ }
+ return true;
+ }
+ return false;
+ }
+};
+
+
+
+}} // namespace detail::shp_read_object
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Tag, typename Geometry>
+struct shp_read_object
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (Geometry)
+ );
+};
+
+
+template <typename LineString>
+struct shp_read_object<linestring_tag, LineString>
+ : detail::shp_read_object::read_linestring<LineString>
+{};
+
+
+
+
+template <typename Polygon>
+struct shp_read_object<polygon_tag, Polygon>
+ : detail::shp_read_object::read_polygon<Polygon>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Geometry>
+inline void read_shapefile(std::string const& filename,
+ std::vector<Geometry>& geometries)
+{
+
+ try
+ {
+ // create shape_reader
+
+ for (int i = 0; i < shape_reader.Count(); i++)
+ {
+ SHPObject* psShape = SHPReadObject(shp_handle, i);
+ Geometry geometry;
+ if (dispatch::shp_read_object<Geometry>(*psShape, geometry))
+ {
+ geometries.push_back(geometry);
+ }
+ SHPDestroyObject( psShape );
+ }
+
+ }
+ catch(std::string s)
+ {
+ throw s;
+ }
+ catch(...)
+ {
+ throw std::string("Other exception");
+ }
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXT_GIS_IO_SHAPELIB_SHP_READ_OBJECT_HPP
diff --git a/src/boost/geometry/extensions/gis/io/veshape/write_veshape.hpp b/src/boost/geometry/extensions/gis/io/veshape/write_veshape.hpp
new file mode 100644
index 0000000..4b4caff
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/veshape/write_veshape.hpp
@@ -0,0 +1,281 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_VESHAPE_WRITE_VESHAPE_HPP
+#define BOOST_GEOMETRY_IO_VESHAPE_WRITE_VESHAPE_HPP
+
+#include <ostream>
+#include <string>
+
+#include <boost/concept/assert.hpp>
+#include <boost/range.hpp>
+
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace veshape
+{
+
+
+// Define the coordinate streamer, specialized for either 2 or 3 dimensions.
+// Any other number of dimensions make no sense for VE, and we have to take care about
+// the order lat,long (--> y,x)
+template <typename P, std::size_t D>
+struct stream_coordinate {};
+
+
+template <typename P>
+struct stream_coordinate<P, 2>
+{
+ template <typename Char, typename Traits>
+ static inline void stream(std::basic_ostream<Char, Traits>& os, P const& p)
+ {
+ os << geometry::get<1>(p) << "," << geometry::get<0>(p);
+ }
+};
+
+template <typename P>
+struct stream_coordinate<P, 3>
+{
+ template <typename Char, typename Traits>
+ static inline void stream(std::basic_ostream<Char, Traits>& os, P const& p)
+ {
+ stream_coordinate<P, 2>::stream(os, p);
+ os << "," << geometry::get<2>(p);
+ }
+};
+
+
+template <typename P>
+struct stream_point
+{
+ template <typename Char, typename Traits>
+ static inline void stream(std::basic_ostream<Char, Traits>& os, P const& p)
+ {
+ os << "new VELatLong(";
+ stream_coordinate<P, dimension<P>::value>::stream(os, p);
+ os << ")";
+ }
+};
+
+
+
+struct prefix_point
+{
+ static inline const char* prefix()
+ { return "new VEShape(VEShapeType.Pushpin, "; }
+
+ static inline const char* postfix()
+ { return ")"; }
+};
+
+struct prefix_linestring
+{
+ static inline const char* prefix()
+ { return "new VEShape(VEShapeType.Polyline, "; }
+
+ static inline const char* postfix()
+ { return ")"; }
+};
+
+
+struct prefix_polygon
+{
+ static inline const char* prefix()
+ { return "new VEShape(VEShapeType.Polygon, "; }
+
+ static inline const char* postfix()
+ { return ")"; }
+};
+
+/*!
+\brief Stream points as \ref VEShape
+*/
+template <typename P, typename Policy>
+struct veshape_point
+{
+ template <typename Char, typename Traits>
+ static inline void stream(std::basic_ostream<Char, Traits>& os, P const& p)
+ {
+ os << Policy::prefix();
+ stream_point<P>::stream(os, p);
+ os << Policy::postfix();
+ }
+
+ private:
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P>) );
+};
+
+/*!
+\brief Stream ranges as VEShape
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename R, typename Policy>
+struct veshape_range
+{
+ template <typename Char, typename Traits>
+ static inline void stream(std::basic_ostream<Char, Traits>& os, R const& range)
+ {
+ typedef typename boost::range_iterator<R const>::type iterator;
+
+ bool first = true;
+
+ os << Policy::prefix() << "new Array(";
+
+ for (iterator it = boost::begin(range); it != boost::end(range); ++it)
+ {
+ os << (first ? "" : ", ");
+ stream_point<point>::stream(os, *it);
+ first = false;
+ }
+
+ os << ")" << Policy::postfix();
+ }
+
+ private:
+ typedef typename boost::range_value<R>::type point;
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point>) );
+};
+
+
+
+template <typename P, typename Policy>
+struct veshape_poly
+{
+ template <typename Char, typename Traits>
+ static inline void stream(std::basic_ostream<Char, Traits>& os, P const& poly)
+ {
+ typedef typename ring_type<P>::type ring;
+
+ veshape_range<ring, Policy>::stream(os, exterior_ring(poly));
+
+ // For VE shapes: inner rings are not supported or undocumented
+ /***
+ for (iterator it = boost::begin(interior_rings(poly));
+ it != boost::end(interior_rings(poly)); it++)
+ {
+ os << ",";
+ veshape_range<ring, null>::stream(os, *it);
+ }
+ os << ")";
+ ***/
+ }
+
+ private:
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<typename point_type<P>::type>) );
+};
+
+
+
+}} // namespace detail::veshape
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+/*!
+\brief Dispatching base struct for VEShape streaming, specialized below per geometry type
+\details Specializations should implement a static method "stream" to stream a geometry
+The static method should have the signature:
+
+template <typename Char, typename Traits>
+static inline void stream(std::basic_ostream<Char, Traits>& os, G const& geometry)
+*/
+template <typename T, typename G>
+struct veshape
+{};
+
+
+template <typename P>
+struct veshape<point_tag, P>
+ : detail::veshape::veshape_point<P, detail::veshape::prefix_point>
+{};
+
+
+template <typename R>
+struct veshape<linestring_tag, R>
+ : detail::veshape::veshape_range<R, detail::veshape::prefix_linestring>
+{};
+
+
+template <typename R>
+struct veshape<ring_tag, R>
+ : detail::veshape::veshape_range<R, detail::veshape::prefix_polygon>
+{};
+
+
+template <typename P>
+struct veshape<polygon_tag, P>
+ : detail::veshape::veshape_poly<P, detail::veshape::prefix_polygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup veshape
+\details Stream manipulator, streams geometry classes as Virtual Earth shape
+*/
+template <typename G>
+class veshape_manip
+{
+public:
+
+ inline veshape_manip(G const& g)
+ : m_geometry(g)
+ {}
+
+ template <typename Char, typename Traits>
+ inline friend std::basic_ostream<Char, Traits>& operator<<(
+ std::basic_ostream<Char, Traits>& os, veshape_manip const& m)
+ {
+ dispatch::veshape<typename tag<G>::type, G>::stream(os, m.m_geometry);
+ os.flush();
+ return os;
+ }
+
+private:
+ G const& m_geometry;
+};
+
+/*!
+\brief Object generator to conveniently stream objects without including streamveshape
+\ingroup veshape
+\par Example:
+Small example showing how to use the veshape helper function
+\dontinclude doxygen_1.cpp
+\skip example_as_veshape_vector
+\line {
+\until }
+*/
+template <typename T>
+inline veshape_manip<T> veshape(T const& t)
+{
+ return veshape_manip<T>(t);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_VESHAPE_WRITE_VESHAPE_HPP
diff --git a/src/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp b/src/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp
new file mode 100644
index 0000000..dbf0602
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp
@@ -0,0 +1,262 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Load/Store values from/to stream of bytes across different endianness.
+
+// Original design of unrolled_byte_loops templates based on
+// endian utility library from Boost C++ Libraries,
+// source: boost/spirit/home/support/detail/integer/endian.hpp
+// Copyright Darin Adler 2000
+// Copyright Beman Dawes 2006, 2009
+// Distributed under the Boost Software License, Version 1.0.
+
+#ifndef BOOST_GEOMETRY_DETAIL_ENDIAN_HPP
+#define BOOST_GEOMETRY_DETAIL_ENDIAN_HPP
+
+#include <cassert>
+#include <climits>
+#include <cstring>
+#include <cstddef>
+
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/endian.hpp>
+#include <boost/type_traits/is_signed.hpp>
+
+#if CHAR_BIT != 8
+#error Platforms with CHAR_BIT != 8 are not supported
+#endif
+
+// TODO: mloskot - add static asserts to validate compile-time pre-conditions
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace endian
+{
+
+// Endianness tag used to indicate load/store directoin
+
+struct big_endian_tag {};
+struct little_endian_tag {};
+
+#ifdef BOOST_BIG_ENDIAN
+typedef big_endian_tag native_endian_tag;
+#else
+typedef little_endian_tag native_endian_tag;
+#endif
+
+// Unrolled loops for loading and storing streams of bytes.
+
+template <typename T, std::size_t N, bool Sign = boost::is_signed<T>::value>
+struct unrolled_byte_loops
+{
+ typedef unrolled_byte_loops<T, N - 1, Sign> next;
+
+ template <typename Iterator>
+ static T load_forward(Iterator& bytes)
+ {
+ T const value = *bytes;
+ ++bytes;
+ return value | (next::load_forward(bytes) << 8);
+ }
+
+ template <typename Iterator>
+ static T load_backward(Iterator& bytes)
+ {
+ T const value = *(bytes - 1);
+ --bytes;
+ return value | (next::load_backward(bytes) << 8);
+ }
+
+ template <typename Iterator>
+ static void store_forward(Iterator& bytes, T value)
+ {
+ *bytes = static_cast<char>(value);
+ next::store_forward(++bytes, value >> 8);
+ }
+
+ template <typename Iterator>
+ static void store_backward(Iterator& bytes, T value)
+ {
+ *(bytes - 1) = static_cast<char>(value);
+ next::store_backward(--bytes, value >> 8);
+ }
+};
+
+template <typename T>
+struct unrolled_byte_loops<T, 1, false>
+{
+ template <typename Iterator>
+ static T load_forward(Iterator& bytes)
+ {
+ return *bytes;
+ }
+
+ template <typename Iterator>
+ static T load_backward(Iterator& bytes)
+ {
+ return *(bytes - 1);
+ }
+
+ template <typename Iterator>
+ static void store_forward(Iterator& bytes, T value)
+ {
+ // typename Iterator::value_type
+ *bytes = static_cast<char>(value);
+ }
+
+ template <typename Iterator>
+ static void store_backward(Iterator& bytes, T value)
+ {
+ *(bytes - 1) = static_cast<char>(value);
+ }
+};
+
+template <typename T>
+struct unrolled_byte_loops<T, 1, true>
+{
+ template <typename Iterator>
+ static T load_forward(Iterator& bytes)
+ {
+ return *reinterpret_cast<const signed char*>(&*bytes);
+ }
+
+ template <typename Iterator>
+ static T load_backward(Iterator& bytes)
+ {
+ return *reinterpret_cast<const signed char*>(&*(bytes - 1));
+ }
+
+ template <typename Iterator>
+ static void store_forward(Iterator& bytes, T value)
+ {
+ BOOST_STATIC_ASSERT((boost::is_signed<typename Iterator::value_type>::value));
+
+ *bytes = static_cast<typename Iterator::value_type>(value);
+ }
+
+ template <typename Iterator>
+ static void store_backward(Iterator& bytes, T value)
+ {
+ BOOST_STATIC_ASSERT((boost::is_signed<typename Iterator::value_type>::value));
+
+ *(bytes - 1) = static_cast<typename Iterator::value_type>(value);
+ }
+};
+
+// load/store operation dispatch
+// E, E - source and target endianness is the same
+// E1, E2 - source and target endianness is different (big-endian <-> little-endian)
+
+template <typename T, std::size_t N, typename Iterator, typename E>
+T load_dispatch(Iterator& bytes, E, E)
+{
+ return unrolled_byte_loops<T, N>::load_forward(bytes);
+}
+
+template <typename T, std::size_t N, typename Iterator, typename E1, typename E2>
+T load_dispatch(Iterator& bytes, E1, E2)
+{
+ std::advance(bytes, N);
+ return unrolled_byte_loops<T, N>::load_backward(bytes);
+}
+
+template <typename T, std::size_t N, typename Iterator, typename E>
+void store_dispatch(Iterator& bytes, T value, E, E)
+{
+ return unrolled_byte_loops<T, N>::store_forward(bytes, value);
+}
+
+template <typename T, std::size_t N, typename Iterator, typename E1, typename E2>
+void store_dispatch(Iterator& bytes, T value, E1, E2)
+{
+ std::advance(bytes, N);
+ return unrolled_byte_loops<T, N>::store_backward(bytes, value);
+}
+
+// numeric value holder for load/store operation
+
+template <typename T>
+struct endian_value_base
+{
+ typedef T value_type;
+ typedef native_endian_tag endian_type;
+
+ endian_value_base() : value(T()) {}
+ explicit endian_value_base(T value) : value(value) {}
+
+ operator T() const
+ {
+ return value;
+ }
+
+protected:
+ T value;
+};
+
+template <typename T, std::size_t N = sizeof(T)>
+struct endian_value : public endian_value_base<T>
+{
+ typedef endian_value_base<T> base;
+
+ endian_value() {}
+ explicit endian_value(T value) : base(value) {}
+
+ template <typename E, typename Iterator>
+ void load(Iterator bytes)
+ {
+ base::value = load_dispatch<T, N>(bytes, typename base::endian_type(), E());
+ }
+
+ template <typename E, typename Iterator>
+ void store(Iterator bytes)
+ {
+ store_dispatch<T, N>(bytes, base::value, typename base::endian_type(), E());
+ }
+};
+
+template <>
+struct endian_value<double, 8> : public endian_value_base<double>
+{
+ typedef endian_value_base<double> base;
+
+ endian_value() {}
+ explicit endian_value(double value) : base(value) {}
+
+ template <typename E, typename Iterator>
+ void load(Iterator bytes)
+ {
+ endian_value<boost::uint64_t, 8> raw;
+ raw.load<E>(bytes);
+
+ double& target_value = base::value;
+ std::memcpy(&target_value, &raw, sizeof(double));
+ }
+
+ template <typename E, typename Iterator>
+ void store(Iterator bytes)
+ {
+ boost::uint64_t raw;
+ double const& source_value = base::value;
+ std::memcpy(&raw, &source_value, sizeof(boost::uint64_t));
+
+ store_dispatch
+ <
+ boost::uint64_t,
+ sizeof(boost::uint64_t)
+ >(bytes, raw, typename base::endian_type(), E());
+ }
+};
+
+}} // namespace detail::endian
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_DETAIL_ENDIAN_HPP
+
diff --git a/src/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp b/src/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp
new file mode 100644
index 0000000..34cd533
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp
@@ -0,0 +1,86 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKB_DETAIL_OGC_HPP
+#define BOOST_GEOMETRY_IO_WKB_DETAIL_OGC_HPP
+
+#include <boost/cstdint.hpp>
+
+namespace boost { namespace geometry
+{
+
+// The well-known binary representation for OGC geometry (WKBGeometry),
+// provides a portable representation of a geometry value as a contiguous
+// stream of bytes. It permits geometry values to be exchanged between
+// a client application and an SQL database in binary form.
+//
+// Basic Type definitions
+// byte : 1 byte
+// uint32 : 32 bit unsigned integer (4 bytes)
+// double : double precision number (8 bytes)
+//
+// enum wkbByteOrder
+// {
+// wkbXDR = 0, // Big Endian
+// wkbNDR = 1 // Little Endian
+// };
+//
+// enum wkbGeometryType
+// {
+// wkbPoint = 1,
+// wkbLineString = 2,
+// wkbPolygon = 3,
+// wkbMultiPoint = 4,
+// wkbMultiLineString = 5,
+// wkbMultiPolygon = 6,
+// wkbGeometryCollection = 7
+// };
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkb
+{
+
+// TODO: Replace 'struct' with scoped enum from <boost/detail/scoped_enum_emulation.hpp>
+// For older Boost, copy
+// <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
+// to
+// <boost/geometry/detail/scoped_enum_emulation.hpp>
+// and use it.
+
+struct byte_order_type
+{
+ enum enum_t
+ {
+ xdr = 0, // wkbXDR, bit-endian
+ ndr = 1, // wkbNDR, little-endian
+ unknown = 2 // not defined by OGC
+ };
+};
+
+struct geometry_type
+{
+ enum enum_t
+ {
+ point = 1,
+ linestring = 2,
+ polygon = 3
+
+ // TODO: Not implemented
+ //multipoint = 4,
+ //multilinestring = 5,
+ //multipolygon = 6,
+ //collection = 7
+ };
+};
+
+}} // namespace detail::endian
+#endif // DOXYGEN_NO_IMPL
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_WKB_DETAIL_OGC_HPP
diff --git a/src/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp b/src/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp
new file mode 100644
index 0000000..48e4d52
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkb/detail/parser.hpp
@@ -0,0 +1,315 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKB_DETAIL_PARSER_HPP
+#define BOOST_GEOMETRY_IO_WKB_DETAIL_PARSER_HPP
+
+#include <cassert>
+#include <cstddef>
+#include <algorithm>
+#include <iterator>
+#include <limits>
+
+#include <boost/concept_check.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/extensions/gis/io/wkb/detail/endian.hpp>
+#include <boost/geometry/extensions/gis/io/wkb/detail/ogc.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkb
+{
+
+template <typename T>
+struct value_parser
+{
+ typedef T value_type;
+
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end, T& value, byte_order_type::enum_t order)
+ {
+ // Very basic pre-conditions check on stream of bytes passed in
+ BOOST_STATIC_ASSERT((
+ boost::is_integral<typename std::iterator_traits<Iterator>::value_type>::value
+ ));
+ BOOST_STATIC_ASSERT((sizeof(boost::uint8_t) ==
+ sizeof(typename std::iterator_traits<Iterator>::value_type)
+ ));
+
+ typedef typename std::iterator_traits<Iterator>::difference_type diff_type;
+ diff_type const required_size = sizeof(T);
+ if (it != end && std::distance(it, end) >= required_size)
+ {
+ typedef endian::endian_value<T> parsed_value_type;
+ parsed_value_type parsed_value;
+
+ // Decide on direcion of endianness translation, detault to native
+ if (byte_order_type::xdr == order)
+ {
+ parsed_value.template load<endian::big_endian_tag>(it);
+ }
+ else if (byte_order_type::ndr == order)
+ {
+ parsed_value.template load<endian::little_endian_tag>(it);
+ }
+ else
+ {
+ parsed_value.template load<endian::native_endian_tag>(it);
+ }
+
+ value = parsed_value;
+ std::advance(it, required_size);
+ return true;
+ }
+
+ return false;
+ }
+};
+
+struct byte_order_parser
+{
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end, byte_order_type::enum_t& order)
+ {
+ boost::uint8_t value;
+ if (value_parser<boost::uint8_t>::parse(it, end, value, byte_order_type::unknown))
+ {
+ if (byte_order_type::unknown > value)
+ {
+ order = byte_order_type::enum_t(value);
+ }
+ return true;
+ }
+ return false;
+ }
+};
+
+struct geometry_type_parser
+{
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end, geometry_type::enum_t& type,
+ byte_order_type::enum_t order)
+ {
+ boost::uint32_t value;
+ if (value_parser<boost::uint32_t>::parse(it, end, value, order))
+ {
+ // TODO: Refine the test when multi* geometries are supported
+
+ boost::uint32_t id = value & 0xff;
+ if (geometry_type::polygon >= id)
+ {
+ type = geometry_type::enum_t(id);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+template <typename P, int I, int N>
+struct parsing_assigner
+{
+ template <typename Iterator>
+ static void run(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order)
+ {
+ typedef typename coordinate_type<P>::type coordinate_type;
+
+ // coordinate type in WKB is always double
+ double value(0);
+ if (value_parser<double>::parse(it, end, value, order))
+ {
+ // actual coordinate type of point may be different
+ set<I>(point, static_cast<coordinate_type>(value));
+ }
+ else
+ {
+ // TODO: mloskot - Report premature termination at coordinate level
+ //throw failed to read coordinate value
+
+ // default initialized value as fallback
+ set<I>(point, coordinate_type());
+ }
+ parsing_assigner<P, I+1, N>::run(it, end, point, order);
+ }
+};
+
+template <typename P, int N>
+struct parsing_assigner<P, N, N>
+{
+ template <typename Iterator>
+ static void run(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order)
+ {
+ // terminate
+ boost::ignore_unused_variable_warning(it);
+ boost::ignore_unused_variable_warning(end);
+ boost::ignore_unused_variable_warning(point);
+ boost::ignore_unused_variable_warning(order);
+ }
+};
+
+template <typename P>
+struct point_parser
+{
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order)
+ {
+ // TODO: mloskot - Add assert on point dimension, 2d only
+
+ geometry_type::enum_t type;
+ if (geometry_type_parser::parse(it, end, type, order))
+ {
+ if (geometry_type::point == type && it != end)
+ {
+ parsing_assigner<P, 0, dimension<P>::value>::run(it, end, point, order);
+ }
+ return true;
+ }
+ return false;
+ }
+};
+
+template <typename C>
+struct point_container_parser
+{
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end, C& container, byte_order_type::enum_t order)
+ {
+ typedef typename point_type<C>::type point_type;
+
+ boost::uint32_t num_points(0);
+ if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
+ {
+ return false;
+ }
+
+ typedef typename std::iterator_traits<Iterator>::difference_type size_type;
+ assert(num_points <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
+
+ size_type const container_size = static_cast<size_type>(num_points);
+ size_type const point_size = dimension<point_type>::value * sizeof(double);
+
+ if (std::distance(it, end) >= (container_size * point_size))
+ {
+ point_type point_buffer;
+ std::back_insert_iterator<C> output(std::back_inserter(container));
+
+ // Read coordinates into point and append point to line (ring)
+ size_type points_parsed = 0;
+ while (points_parsed < container_size && it != end)
+ {
+ parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, order);
+ output = point_buffer;
+ ++output;
+ ++points_parsed;
+ }
+
+ if (container_size != points_parsed)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
+
+template <typename L>
+struct linestring_parser
+{
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end, L& linestring, byte_order_type::enum_t order)
+ {
+ typedef typename point_type<L>::type point_type;
+
+ geometry_type::enum_t type;
+ if (!geometry_type_parser::parse(it, end, type, order))
+ {
+ return false;
+ }
+
+ if (geometry_type::linestring != type)
+ {
+ return false;
+ }
+
+ assert(it != end);
+ return point_container_parser<L>::parse(it, end, linestring, order);
+ }
+};
+
+template <typename Polygon>
+struct polygon_parser
+{
+ template <typename Iterator>
+ static bool parse(Iterator& it, Iterator end, Polygon& polygon, byte_order_type::enum_t order)
+ {
+ geometry_type::enum_t type;
+ if (!geometry_type_parser::parse(it, end, type, order))
+ {
+ return false;
+ }
+
+ boost::uint32_t num_rings(0);
+ if (geometry_type::polygon != type ||
+ !value_parser<boost::uint32_t>::parse(it, end, num_rings, order))
+ {
+ return false;
+ }
+
+ typedef typename ring_type<Polygon>::type ring_type;
+
+ std::size_t rings_parsed = 0;
+ while (rings_parsed < num_rings && it != end) //while (rings_parsed < num_rings && it != end)
+ {
+ if (0 == rings_parsed)
+ {
+ ring_type& ring0 = exterior_ring(polygon);
+ if (!point_container_parser<ring_type>::parse(it, end, ring0, order))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ interior_rings(polygon).resize(rings_parsed);
+ ring_type& ringN = interior_rings(polygon).back();
+ if (!point_container_parser<ring_type>::parse(it, end, ringN, order))
+ {
+ return false;
+ }
+ }
+ ++rings_parsed;
+ }
+
+ if (num_rings != rings_parsed)
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+}} // namespace detail::wkb
+#endif // DOXYGEN_NO_IMPL
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_IO_WKB_DETAIL_PARSER_HPP
diff --git a/src/boost/geometry/extensions/gis/io/wkb/read_wkb.hpp b/src/boost/geometry/extensions/gis/io/wkb/read_wkb.hpp
new file mode 100644
index 0000000..69662b5
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkb/read_wkb.hpp
@@ -0,0 +1,108 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKB_READ_WKB_HPP
+#define BOOST_GEOMETRY_IO_WKB_READ_WKB_HPP
+
+#include <iterator>
+
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/static_assert.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/extensions/gis/io/wkb/detail/parser.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename G>
+struct read_wkb {};
+
+template <typename G>
+struct read_wkb<point_tag, G>
+{
+ template <typename Iterator>
+ static inline bool parse(Iterator& it, Iterator end, G& geometry,
+ detail::wkb::byte_order_type::enum_t order)
+ {
+ return detail::wkb::point_parser<G>::parse(it, end, geometry, order);
+ }
+};
+
+template <typename G>
+struct read_wkb<linestring_tag, G>
+{
+ template <typename Iterator>
+ static inline bool parse(Iterator& it, Iterator end, G& geometry,
+ detail::wkb::byte_order_type::enum_t order)
+ {
+ geometry::clear(geometry);
+ return detail::wkb::linestring_parser<G>::parse(it, end, geometry, order);
+ }
+};
+
+template <typename G>
+struct read_wkb<polygon_tag, G>
+{
+ template <typename Iterator>
+ static inline bool parse(Iterator& it, Iterator end, G& geometry,
+ detail::wkb::byte_order_type::enum_t order)
+ {
+ geometry::clear(geometry);
+ return detail::wkb::polygon_parser<G>::parse(it, end, geometry, order);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Iterator, typename G>
+inline bool read_wkb(Iterator begin, Iterator end, G& geometry)
+{
+ // Stream of bytes can only be parsed using random access iterator.
+ BOOST_STATIC_ASSERT((
+ boost::is_convertible
+ <
+ typename std::iterator_traits<Iterator>::iterator_category,
+ const std::random_access_iterator_tag&
+ >::value));
+
+ detail::wkb::byte_order_type::enum_t byte_order;
+ if (detail::wkb::byte_order_parser::parse(begin, end, byte_order))
+ {
+ return dispatch::read_wkb
+ <
+ typename tag<G>::type,
+ G
+ >::parse(begin, end, geometry, byte_order);
+ }
+
+ return false;
+}
+
+template <typename ByteType, typename G>
+inline bool read_wkb(ByteType const* bytes, std::size_t length, G& geometry)
+{
+ BOOST_STATIC_ASSERT((boost::is_integral<ByteType>::value));
+ BOOST_STATIC_ASSERT((sizeof(boost::uint8_t) == sizeof(ByteType)));
+
+ ByteType const* begin = bytes;
+ ByteType const* const end = bytes + length;
+
+ return read_wkb(begin, end, geometry);
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_WKB_READ_WKB_HPP
diff --git a/src/boost/geometry/extensions/gis/io/wkb/utility.hpp b/src/boost/geometry/extensions/gis/io/wkb/utility.hpp
new file mode 100644
index 0000000..fd5e1dc
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkb/utility.hpp
@@ -0,0 +1,92 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKB_UTILITY_HPP
+#define BOOST_GEOMETRY_IO_WKB_UTILITY_HPP
+
+#include <iomanip>
+#include <iterator>
+#include <sstream>
+#include <string>
+
+#include <boost/cstdint.hpp>
+
+namespace boost { namespace geometry
+{
+
+// TODO: Waiting for errors handling design, eventually return bool
+// may be replaced to throw exception.
+
+template <typename OutputIterator>
+bool hex2wkb(std::string const& hex, OutputIterator bytes)
+{
+ // Bytes can be only written to output iterator.
+ BOOST_STATIC_ASSERT((boost::is_convertible<
+ typename std::iterator_traits<OutputIterator>::iterator_category,
+ const std::output_iterator_tag&>::value));
+
+ std::string::size_type const byte_size = 2;
+ if (0 != hex.size() % byte_size)
+ {
+ return false;
+ }
+
+ std::string::size_type const size = hex.size() / byte_size;
+ for (std::string::size_type i = 0; i < size; ++i)
+ {
+ // TODO: This is confirmed performance killer - to be replaced with static char-to-byte map --mloskot
+ std::istringstream iss(hex.substr(i * byte_size, byte_size));
+ unsigned int byte(0);
+ if (!(iss >> std::hex >> byte))
+ {
+ return false;
+ }
+ *bytes = static_cast<boost::uint8_t>(byte);
+ ++bytes;
+ }
+
+ return true;
+}
+
+template <typename Iterator>
+bool wkb2hex(Iterator begin, Iterator end, std::string& hex)
+{
+ // Stream of bytes can only be passed using random access iterator.
+ BOOST_STATIC_ASSERT((boost::is_convertible<
+ typename std::iterator_traits<Iterator>::iterator_category,
+ const std::random_access_iterator_tag&>::value));
+
+ const char hexalpha[] = "0123456789ABCDEF";
+ char hexbyte[3] = { 0 };
+ std::ostringstream oss;
+
+ Iterator it = begin;
+ while (it != end)
+ {
+ boost::uint8_t byte = static_cast<boost::uint8_t>(*it);
+ hexbyte[0] = hexalpha[(byte >> 4) & 0xf];
+ hexbyte[1] = hexalpha[byte & 0xf];
+ hexbyte[2] = '\0';
+ oss << std::setw(2) << hexbyte;
+ ++it;
+ }
+
+ // TODO: Binary streams can be big.
+ // Does it make sense to request stream buffer of proper (large) size or
+ // use incremental appends within while-loop?
+ hex = oss.str();
+
+ // Poor-man validation, no performance penalty expected
+ // because begin/end always are random access iterators.
+ return hex.size() == (2 * std::distance(begin, end));
+}
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_WKB_UTILITY_HPP
diff --git a/src/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp b/src/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp
new file mode 100644
index 0000000..e3e58d7
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp
@@ -0,0 +1,68 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
+
+
+#if defined(BOOST_MSVC_FULL_VER)
+#pragma message ("WARNING: wkt is moved to boost/geometry/domains/gis/io/wkt, please update include file")
+#else
+#warning "wkt is moved to boost/geometry/domains/gis/io/wkt, please update include file"
+#endif
+
+
+#include <boost/geometry/domains/gis/io/wkt/read_wkt.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief Parses OGC Well-Known Text (\ref WKT) and outputs using an output iterator
+\ingroup wkt
+\param wkt string containing \ref WKT
+\param out output iterator
+\note This function is deprecated!
+\note Because the output iterator doesn't always have the type value_type, it should be
+specified in the function call.
+\par Example:
+Small example showing how to use read_wkt with an output iterator
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_output_iterator
+\line {
+\until }
+*/
+template <typename Geometry, typename OutputIterator>
+inline void read_wkt(std::string const& wkt, OutputIterator out)
+{
+ geometry::concept::check<Geometry>();
+
+ typedef typename point_type<Geometry>::type point_type;
+
+ std::string const& tag =
+ geometry_id<Geometry>::value == 2 ? "linestring" : "polygon";
+
+ detail::wkt::tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ detail::wkt::tokenizer::iterator it;
+ if (detail::wkt::initialize<point_type>(tokens, tag, wkt, it))
+ {
+ detail::wkt::container_inserter<point_type>::apply(it, tokens.end(), wkt, out);
+ }
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
diff --git a/src/boost/geometry/extensions/gis/io/wkt/readme.txt b/src/boost/geometry/extensions/gis/io/wkt/readme.txt
new file mode 100644
index 0000000..2094d1a
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkt/readme.txt
@@ -0,0 +1,15 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+Note, the wkt is moved to /boost/geometry/domains/gis/io/wkt
diff --git a/src/boost/geometry/extensions/gis/io/wkt/stream_wkt.hpp b/src/boost/geometry/extensions/gis/io/wkt/stream_wkt.hpp
new file mode 100644
index 0000000..7de5523
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkt/stream_wkt.hpp
@@ -0,0 +1,46 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
+
+#include <boost/geometry/domains/gis/io/wkt/write_wkt.hpp>
+
+// This short file contains only one manipulator, streaming as WKT
+// Don't move contents to as_wkt, developers must be able to choose how to stream
+
+// Don't use namespace boost::geometry, to enable the library to stream custom geometries which
+// are living outside the namespace boost { namespace geometry
+
+//namespace boost { namespace geometry
+//{
+
+
+/*!
+\brief Streams a geometry as Well-Known Text
+\ingroup wkt
+*/
+template<typename Char, typename Traits, typename Geometry>
+inline std::basic_ostream<Char,Traits>& operator<<
+ (
+ std::basic_ostream<Char,Traits> &os,
+ Geometry const& geom
+ )
+{
+ os << boost::geometry::wkt(geom);
+ return os;
+}
+
+//}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
diff --git a/src/boost/geometry/extensions/gis/io/wkt/wkt.hpp b/src/boost/geometry/extensions/gis/io/wkt/wkt.hpp
new file mode 100644
index 0000000..cb7c995
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkt/wkt.hpp
@@ -0,0 +1,32 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_WKT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_WKT_HPP
+
+
+#if defined(BOOST_MSVC_FULL_VER)
+#pragma message ("WARNING: wkt is moved to boost/geometry/domains/gis/io/wkt, please update include file")
+#else
+#warning "wkt is moved to boost/geometry/domains/gis/io/wkt, please update include file"
+#endif
+
+
+#include <boost/geometry/domains/gis/io/wkt/read_wkt.hpp>
+#include <boost/geometry/domains/gis/io/wkt/write_wkt.hpp>
+
+#include <boost/geometry/domains/gis/io/wkt/read_wkt_multi.hpp>
+#include <boost/geometry/domains/gis/io/wkt/write_wkt_multi.hpp>
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_WKT_HPP
diff --git a/src/boost/geometry/extensions/gis/io/wkt/write_wkt.hpp b/src/boost/geometry/extensions/gis/io/wkt/write_wkt.hpp
new file mode 100644
index 0000000..c1bfdb2
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/io/wkt/write_wkt.hpp
@@ -0,0 +1,44 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
+
+
+#if defined(BOOST_MSVC_FULL_VER)
+#pragma message ("WARNING: wkt is moved to boost/geometry/domains/gis/io/wkt, please update include file")
+#else
+#warning "wkt is moved to boost/geometry/domains/gis/io/wkt, please update include file"
+#endif
+
+
+#include <boost/geometry/domains/gis/io/wkt/write_wkt.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+// Backward compatibility - NOTE THIS IS DEPRECATED
+template <typename Geometry>
+inline wkt_manipulator<Geometry> make_wkt(Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ return wkt_manipulator<Geometry>(geometry);
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
diff --git a/src/boost/geometry/extensions/gis/latlong/detail/graticule.hpp b/src/boost/geometry/extensions/gis/latlong/detail/graticule.hpp
new file mode 100644
index 0000000..84f519e
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/latlong/detail/graticule.hpp
@@ -0,0 +1,238 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_DETAIL_GRATICULE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_DETAIL_GRATICULE_HPP
+
+#include <cmath>
+#include <sstream>
+#include <string>
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+ \brief Cardinal directions.
+ \ingroup cs
+ \details They are used in the dms-class. When specified by the library user,
+ north/east/south/west is, in general, enough. When parsed or received by an algorithm,
+ the user knows it it is lat/long but not more
+*/
+enum cd_selector
+{
+ /*cd_none, */
+ north,
+ east,
+ south,
+ west,
+ cd_lat,
+ cd_lon
+};
+
+/*!
+ \brief Utility class to assign poinst with degree,minute,second
+ \ingroup cs
+ \note Normally combined with latitude and longitude classes
+ \tparam CardinalDir selects if it is north/south/west/east
+ \tparam coordinate value, double/float
+ \par Example:
+ Example showing how to use the dms class
+ \dontinclude doxygen_1.cpp
+ \skip example_dms
+ \line {
+ \until }
+*/
+template <cd_selector CardinalDir, typename T = double>
+class dms
+{
+public:
+
+ /// Constructs with a value
+ inline explicit dms(T v)
+ : m_value(v)
+ {}
+
+ /// Constructs with a degree, minute, optional second
+ inline explicit dms(int d, int m, T s = 0.0)
+ {
+ double v = ((CardinalDir == west || CardinalDir == south) ? -1.0 : 1.0)
+ * (double(d) + (m / 60.0) + (s / 3600.0));
+
+ m_value = boost::numeric_cast<T>(v);
+ }
+
+ // Prohibit automatic conversion to T
+ // because this would enable lon(dms<south>)
+ // inline operator T() const { return m_value; }
+
+ /// Explicit conversion to T (double/float)
+ inline const T& as_value() const
+ {
+ return m_value;
+ }
+
+ /// Get degrees as integer, minutes as integer, seconds as double.
+ inline void get_dms(int& d, int& m, double& s,
+ bool& positive, char& cardinal) const
+ {
+ double value = m_value;
+
+ // Set to normal earth latlong coordinates
+ while (value < -180)
+ {
+ value += 360;
+ }
+ while (value > 180)
+ {
+ value -= 360;
+ }
+ // Make positive and indicate this
+ positive = value > 0;
+
+ // Todo: we might implement template/specializations here
+ // Todo: if it is "west" and "positive", make east? or keep minus sign then?
+
+ cardinal = ((CardinalDir == cd_lat && positive) ? 'N'
+ : (CardinalDir == cd_lat && !positive) ? 'S'
+ : (CardinalDir == cd_lon && positive) ? 'E'
+ : (CardinalDir == cd_lon && !positive) ? 'W'
+ : (CardinalDir == east) ? 'E'
+ : (CardinalDir == west) ? 'W'
+ : (CardinalDir == north) ? 'N'
+ : (CardinalDir == south) ? 'S'
+ : ' ');
+
+ value = geometry::math::abs(value);
+
+ // Calculate the values
+ double fraction = 0;
+ double integer = 0;
+ fraction = std::modf(value, &integer);
+ d = int(integer);
+ s = 60.0 * std::modf(fraction * 60.0, &integer);
+ m = int(integer);
+ }
+
+ /// Get degrees, minutes, seconds as a string, separators can be specified optionally
+ inline std::string get_dms(std::string const& ds = " ",
+ const std::string& ms = "'",
+ const std::string& ss = "\"") const
+ {
+ double s = 0;
+ int d = 0;
+ int m = 0;
+ bool positive = false;
+ char cardinal = 0;
+ get_dms(d, m, s, positive, cardinal);
+ std::ostringstream out;
+ out << d << ds << m << ms << s << ss << " " << cardinal;
+
+ return out.str();
+ }
+
+private:
+
+ T m_value;
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+/*!
+ \brief internal base class for latitude and longitude classes
+ \details The latitude longitude classes define different types for lat and lon. This is convenient
+ to construct latlong class without ambiguity.
+ \note It is called graticule, after <em>"This latitude/longitude "webbing" is known as the common
+ graticule" (http://en.wikipedia.org/wiki/Geographic_coordinate_system)</em>
+ \tparam S latitude/longitude
+ \tparam T coordinate type, double float or int
+*/
+template <typename T>
+class graticule
+{
+public:
+
+ // TODO: Pass 'v' by const-ref
+ inline explicit graticule(T v) : m_v(v) {}
+ inline operator T() const { return m_v; }
+
+private:
+
+ T m_v;
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+ \brief Utility class to assign points with latitude value (north/south)
+ \ingroup cs
+ \tparam T coordinate type, double / float
+ \note Often combined with dms class
+*/
+template <typename T = double>
+class latitude : public detail::graticule<T>
+{
+public:
+
+ /// Can be constructed with a value
+ inline explicit latitude(T v)
+ : detail::graticule<T>(v)
+ {}
+
+ /// Can be constructed with a NORTH dms-class
+ inline explicit latitude(dms<north,T> const& v)
+ : detail::graticule<T>(v.as_value())
+ {}
+
+ /// Can be constructed with a SOUTH dms-class
+ inline explicit latitude(dms<south,T> const& v)
+ : detail::graticule<T>(v.as_value())
+ {}
+};
+
+/*!
+\brief Utility class to assign points with longitude value (west/east)
+\ingroup cs
+\tparam T coordinate type, double / float
+\note Often combined with dms class
+*/
+template <typename T = double>
+class longitude : public detail::graticule<T>
+{
+public:
+
+ /// Can be constructed with a value
+ inline explicit longitude(T v)
+ : detail::graticule<T>(v)
+ {}
+
+ /// Can be constructed with a WEST dms-class
+ inline explicit longitude(dms<west, T> const& v)
+ : detail::graticule<T>(v.as_value())
+ {}
+
+ /// Can be constructed with an EAST dms-class
+ inline explicit longitude(dms<east, T> const& v)
+ : detail::graticule<T>(v.as_value())
+ {}
+};
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_DETAIL_GRATICULE_HPP
diff --git a/src/boost/geometry/extensions/gis/latlong/latlong.hpp b/src/boost/geometry/extensions/gis/latlong/latlong.hpp
new file mode 100644
index 0000000..4b354ca
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/latlong/latlong.hpp
@@ -0,0 +1,54 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_HPP
+
+
+#include <boost/geometry/geometries/geometries.hpp>
+#include <boost/geometry/extensions/gis/latlong/point_ll.hpp>
+
+
+#include <boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp>
+#include <boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp>
+#include <boost/geometry/extensions/gis/geographic/strategies/distance_cross_track.hpp>
+
+namespace boost { namespace geometry
+{
+
+/*
+DEPRECATED
+namespace model
+{
+
+typedef point_ll<double, cs::geographic<degree> > point_ll_deg;
+typedef linestring<point_ll_deg> linestring_ll_deg;
+typedef linear_ring<point_ll_deg> ring_ll_deg;
+typedef polygon<point_ll_deg> polygon_ll_deg;
+typedef box<point_ll_deg> box_ll_deg;
+typedef segment<point_ll_deg> segment_ll_deg;
+
+typedef point_ll<double, cs::geographic<radian> > point_ll_rad;
+typedef linestring<point_ll_rad> linestring_ll_rad;
+typedef linear_ring<point_ll_rad> ring_ll_rad;
+typedef polygon<point_ll_rad> polygon_ll_rad;
+typedef box<point_ll_rad> box_ll_rad;
+typedef segment<point_ll_rad> segment_ll_rad;
+
+} // namespace model
+*/
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_HPP
diff --git a/src/boost/geometry/extensions/gis/latlong/point_ll.hpp b/src/boost/geometry/extensions/gis/latlong/point_ll.hpp
new file mode 100644
index 0000000..1740d1a
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/latlong/point_ll.hpp
@@ -0,0 +1,269 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_POINT_LL_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_POINT_LL_HPP
+
+#include <cstddef>
+#include <sstream>
+#include <string>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/geometries/point.hpp>
+
+#include <boost/geometry/extensions/gis/latlong/detail/graticule.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+namespace model { namespace ll
+{
+
+/*!
+ \brief Point using spherical coordinates \a lat and \a lon, on Earth
+ \ingroup Geometry
+ \details The point_ll class implements a point with lat and lon functions.
+ It can be constructed using latitude and longitude classes. The latlong
+ class can be defined in degrees or in radians. There is a conversion method
+ from degree to radian, and from radian to degree.
+ \tparam Units units,defaults to degree
+ \tparam CoordinateType coordinate type, double (the default) or float
+ (it might be int as well)
+ \tparam CoordinateSystem coordinate system, should include NOT degree/radian
+ indication, should be e.g. cs::geographic or cs::spherical
+ \tparam Dimensions number of dimensions
+ \note There is NO constructor with two values to avoid
+ exchanging lat and long
+ \note Construction with latitude and longitude can be done in both orders,
+ so lat/long and long/lat
+ \par Example:
+ Example showing how the point_ll class can be constructed. Note that it
+ can also be constructed using
+ decimal degrees (43.123).
+ \dontinclude doxygen_1.cpp
+ \skip example_point_ll_construct
+ \line {
+ \until }
+*/
+template
+<
+ typename Units = degree,
+ typename CoordinateType = double,
+ template<typename> class CoordinateSystem = cs::geographic,
+ std::size_t Dimensions = 2
+>
+class point : public model::point
+ <
+ CoordinateType,
+ Dimensions,
+ CoordinateSystem<Units>
+ >
+{
+ typedef model::point
+ <
+ CoordinateType,
+ Dimensions,
+ CoordinateSystem<Units>
+ >
+ base_type;
+public:
+
+ /// Default constructor, does not initialize anything
+ inline point() : base_type() {}
+
+ /// Constructor with longitude/latitude
+ inline point(longitude<CoordinateType> const& lo,
+ latitude<CoordinateType> const& la)
+ : base_type(lo, la) {}
+
+ /// Constructor with latitude/longitude
+ inline point(latitude<CoordinateType> const& la,
+ longitude<CoordinateType> const& lo)
+ : base_type(lo, la) {}
+
+ /// Get longitude
+ inline CoordinateType const& lon() const
+ { return this->template get<0>(); }
+
+ /// Get latitude
+ inline CoordinateType const& lat() const
+ { return this->template get<1>(); }
+
+ /// Set longitude
+ inline void lon(CoordinateType const& v)
+ { this->template set<0>(v); }
+
+ /// Set latitude
+ inline void lat(CoordinateType const& v)
+ { this->template set<1>(v); }
+
+ /// Set longitude using dms class
+ inline void lon(dms<east, CoordinateType> const& v)
+ {
+ this->template set<0>(v.as_value());
+ }
+ inline void lon(dms<west, CoordinateType> const& v)
+ {
+ this->template set<0>(v.as_value());
+ }
+
+ inline void lat(dms<north, CoordinateType> const& v)
+ {
+ this->template set<1>(v.as_value());
+ }
+ inline void lat(dms<south, CoordinateType> const& v)
+ {
+ this->template set<1>(v.as_value());
+ }
+};
+
+
+}} // namespace model::ll
+
+// Adapt the point_ll to the concept
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+ typename Units,
+ typename CoordinateType,
+ template<typename> class CoordinateSystem,
+ std::size_t DimensionCount
+>
+struct tag
+ <
+ model::ll::point
+ <
+ Units,
+ CoordinateType,
+ CoordinateSystem,
+ DimensionCount
+ >
+ >
+{
+ typedef point_tag type;
+};
+
+template
+<
+ typename Units,
+ typename CoordinateType,
+ template<typename> class CoordinateSystem,
+ std::size_t DimensionCount
+>
+struct coordinate_type
+ <
+ model::ll::point
+ <
+ Units,
+ CoordinateType,
+ CoordinateSystem,
+ DimensionCount
+ >
+ >
+{
+ typedef CoordinateType type;
+};
+
+template
+<
+ typename Units,
+ typename CoordinateType,
+ template<typename> class CoordinateSystem,
+ std::size_t DimensionCount
+>
+struct coordinate_system
+ <
+ model::ll::point
+ <
+ Units,
+ CoordinateType,
+ CoordinateSystem,
+ DimensionCount
+ >
+ >
+{
+ typedef CoordinateSystem<Units> type;
+};
+
+template
+<
+ typename Units,
+ typename CoordinateType,
+ template<typename> class CoordinateSystem,
+ std::size_t DimensionCount
+>
+struct dimension
+ <
+ model::ll::point
+ <
+ Units,
+ CoordinateType,
+ CoordinateSystem,
+ DimensionCount
+ >
+ >
+ : boost::mpl::int_<DimensionCount>
+{};
+
+template
+<
+ typename Units,
+ typename CoordinateType,
+ template<typename> class CoordinateSystem,
+ std::size_t DimensionCount,
+ std::size_t Dimension
+>
+struct access
+ <
+ model::ll::point
+ <
+ Units,
+ CoordinateType,
+ CoordinateSystem,
+ DimensionCount
+ >,
+ Dimension
+ >
+{
+ typedef model::ll::point
+ <
+ Units,
+ CoordinateType,
+ CoordinateSystem,
+ DimensionCount
+ > type;
+
+ static inline CoordinateType get(type const& p)
+ {
+ return p.template get<Dimension>();
+ }
+
+ static inline void set(type& p, CoordinateType const& value)
+ {
+ p.template set<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_LATLONG_POINT_LL_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/epsg.hpp b/src/boost/geometry/extensions/gis/projections/epsg.hpp
new file mode 100644
index 0000000..46501b3
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/epsg.hpp
@@ -0,0 +1,3568 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_EPGS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_EPGS_HPP
+
+
+#include <boost/geometry/extensions/gis/projections/parameters.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_init.hpp>
+
+// This file is OPTIONAL
+// Only to be included if EPSG codes are necessary.
+// It is not included automatically
+
+namespace boost { namespace geometry { namespace projection
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+ inline std::string code_to_string(int code)
+ {
+ switch(code)
+ {
+
+ case 2000 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +units=m";
+ case 2001 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +units=m";
+ case 2002 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +towgs84=725,685,536,0,0,0,0 +units=m";
+ case 2003 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +towgs84=72,213.7,93,0,0,0,0 +units=m";
+ case 2004 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +towgs84=174,359,365,0,0,0,0 +units=m";
+ case 2005 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +units=m";
+ case 2006 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +towgs84=-149,128,296,0,0,0,0 +units=m";
+ case 2007 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +towgs84=195.671,332.517,274.607,0,0,0,0 +units=m";
+ case 2008 : return "+proj=tmerc +lat_0=0 +lon_0=-55.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2009 : return "+proj=tmerc +lat_0=0 +lon_0=-58.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2010 : return "+proj=tmerc +lat_0=0 +lon_0=-61.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2011 : return "+proj=tmerc +lat_0=0 +lon_0=-64.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2012 : return "+proj=tmerc +lat_0=0 +lon_0=-67.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2013 : return "+proj=tmerc +lat_0=0 +lon_0=-70.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2014 : return "+proj=tmerc +lat_0=0 +lon_0=-73.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2015 : return "+proj=tmerc +lat_0=0 +lon_0=-76.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2016 : return "+proj=tmerc +lat_0=0 +lon_0=-79.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2017 : return "+proj=tmerc +lat_0=0 +lon_0=-73.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2018 : return "+proj=tmerc +lat_0=0 +lon_0=-76.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2019 : return "+proj=tmerc +lat_0=0 +lon_0=-79.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2020 : return "+proj=tmerc +lat_0=0 +lon_0=-82.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2021 : return "+proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2022 : return "+proj=tmerc +lat_0=0 +lon_0=-84 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2023 : return "+proj=tmerc +lat_0=0 +lon_0=-87 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2024 : return "+proj=tmerc +lat_0=0 +lon_0=-90 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2025 : return "+proj=tmerc +lat_0=0 +lon_0=-93 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2026 : return "+proj=tmerc +lat_0=0 +lon_0=-96 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +units=m";
+ case 2027 : return "+proj=utm +zone=15 +ellps=clrk66 +units=m";
+ case 2028 : return "+proj=utm +zone=16 +ellps=clrk66 +units=m";
+ case 2029 : return "+proj=utm +zone=17 +ellps=clrk66 +units=m";
+ case 2030 : return "+proj=utm +zone=18 +ellps=clrk66 +units=m";
+ case 2031 : return "+proj=utm +zone=17 +ellps=clrk66 +units=m";
+ case 2032 : return "+proj=utm +zone=18 +ellps=clrk66 +units=m";
+ case 2033 : return "+proj=utm +zone=19 +ellps=clrk66 +units=m";
+ case 2034 : return "+proj=utm +zone=20 +ellps=clrk66 +units=m";
+ case 2035 : return "+proj=utm +zone=21 +ellps=clrk66 +units=m";
+ case 2036 : return "+proj=sterea +lat_0=46.5 +lon_0=-66.5 +k=0.999912 +x_0=2500000 +y_0=7500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2037 : return "+proj=utm +zone=19 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2038 : return "+proj=utm +zone=20 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2039 : return "+proj=tmerc +lat_0=31.73439361111111 +lon_0=35.20451694444445 +k=1.0000067 +x_0=219529.584 +y_0=626907.39 +ellps=GRS80 +towgs84=-48,55,52,0,0,0,0 +units=m";
+ case 2040 : return "+proj=utm +zone=30 +ellps=clrk80 +towgs84=-125,53,467,0,0,0,0 +units=m";
+ case 2041 : return "+proj=utm +zone=30 +ellps=clrk80 +towgs84=-124.76,53,466.79,0,0,0,0 +units=m";
+ case 2042 : return "+proj=utm +zone=29 +ellps=clrk80 +towgs84=-125,53,467,0,0,0,0 +units=m";
+ case 2043 : return "+proj=utm +zone=29 +ellps=clrk80 +towgs84=-124.76,53,466.79,0,0,0,0 +units=m";
+ case 2044 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=18500000 +y_0=0 +ellps=krass +towgs84=-17.51,-108.32,-62.39,0,0,0,0 +units=m";
+ case 2045 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=19500000 +y_0=0 +ellps=krass +towgs84=-17.51,-108.32,-62.39,0,0,0,0 +units=m";
+ case 2056 : return "+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m";
+ case 2057 : return "+proj=omerc +lat_0=27.51882880555555 +lonc=52.60353916666667 +alpha=0.5716611944444444 +k=0.999895934 +x_0=658377.437 +y_0=3044969.194 +ellps=intl +towgs84=-133.63,-157.5,-158.62,0,0,0,0 +units=m";
+ case 2058 : return "+proj=utm +zone=38 +ellps=intl +units=m";
+ case 2059 : return "+proj=utm +zone=39 +ellps=intl +units=m";
+ case 2060 : return "+proj=utm +zone=40 +ellps=intl +units=m";
+ case 2061 : return "+proj=utm +zone=41 +ellps=intl +units=m";
+ case 2062 : return "+proj=lcc +lat_1=40 +lat_0=40 +lon_0=0 +k_0=0.9988085293 +x_0=600000 +y_0=600000 +a=6378298.3 +b=6356657.142669561 +pm=madrid +units=m";
+ case 2063 : return "+proj=utm +zone=28 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m";
+ case 2064 : return "+proj=utm +zone=29 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m";
+ case 2065 : return "+proj=krovak +lat_0=49.5 +lon_0=42.5 +alpha=30.28813972222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 2066 : return "+proj=cass +lat_0=11.25217861111111 +lon_0=-60.68600888888889 +x_0=37718.66159325 +y_0=36209.91512952 +a=6378293.645208759 +b=6356617.987679838 +to_meter=0.201166195164";
+ case 2067 : return "+proj=utm +zone=20 +ellps=intl +units=m";
+ case 2068 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2069 : return "+proj=tmerc +lat_0=0 +lon_0=11 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2070 : return "+proj=tmerc +lat_0=0 +lon_0=13 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2071 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2072 : return "+proj=tmerc +lat_0=0 +lon_0=17 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2073 : return "+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2074 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2075 : return "+proj=tmerc +lat_0=0 +lon_0=23 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2076 : return "+proj=tmerc +lat_0=0 +lon_0=25 +k=0.9999 +x_0=200000 +y_0=0 +ellps=intl +units=m";
+ case 2077 : return "+proj=utm +zone=32 +ellps=intl +units=m";
+ case 2078 : return "+proj=utm +zone=33 +ellps=intl +units=m";
+ case 2079 : return "+proj=utm +zone=34 +ellps=intl +units=m";
+ case 2080 : return "+proj=utm +zone=35 +ellps=intl +units=m";
+ case 2081 : return "+proj=tmerc +lat_0=-90 +lon_0=-69 +k=1 +x_0=2500000 +y_0=0 +ellps=intl +units=m";
+ case 2082 : return "+proj=tmerc +lat_0=-90 +lon_0=-69 +k=1 +x_0=2500000 +y_0=0 +ellps=intl +towgs84=27.5,14,186.4,0,0,0,0 +units=m";
+ case 2083 : return "+proj=tmerc +lat_0=-90 +lon_0=-69 +k=1 +x_0=2500000 +y_0=0 +ellps=intl +units=m";
+ case 2084 : return "+proj=utm +zone=19 +south +ellps=intl +units=m";
+ case 2085 : return "+proj=lcc +lat_1=22.35 +lat_0=22.35 +lon_0=-81 +k_0=0.99993602 +x_0=500000 +y_0=280296.016 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 2086 : return "+proj=lcc +lat_1=20.71666666666667 +lat_0=20.71666666666667 +lon_0=-76.83333333333333 +k_0=0.99994848 +x_0=500000 +y_0=229126.939 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 2087 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=0.9996 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 2088 : return "+proj=tmerc +lat_0=0 +lon_0=11 +k=0.9996 +x_0=500000 +y_0=0 +a=6378249.2 +b=6356515 +units=m";
+ case 2089 : return "+proj=utm +zone=38 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2090 : return "+proj=utm +zone=39 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2091 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=8500000 +y_0=0 +ellps=krass +towgs84=-76,-138,67,0,0,0,0 +units=m";
+ case 2092 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=9500000 +y_0=0 +ellps=krass +towgs84=-76,-138,67,0,0,0,0 +units=m";
+ case 2093 : return "+proj=tmerc +lat_0=0 +lon_0=106 +k=1 +x_0=500000 +y_0=0 +ellps=krass +towgs84=-17.51,-108.32,-62.39,0,0,0,0 +units=m";
+ case 2094 : return "+proj=tmerc +lat_0=0 +lon_0=106 +k=0.9996 +x_0=500000 +y_0=0 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 2095 : return "+proj=utm +zone=28 +ellps=intl +towgs84=-173,253,27,0,0,0,0 +units=m";
+ case 2096 : return "+proj=tmerc +lat_0=38 +lon_0=129 +k=1 +x_0=200000 +y_0=500000 +ellps=bessel +units=m";
+ case 2097 : return "+proj=tmerc +lat_0=38 +lon_0=127 +k=1 +x_0=200000 +y_0=500000 +ellps=bessel +units=m";
+ case 2098 : return "+proj=tmerc +lat_0=38 +lon_0=125 +k=1 +x_0=200000 +y_0=500000 +ellps=bessel +units=m";
+ case 2099 : return "+proj=cass +lat_0=25.38236111111111 +lon_0=50.76138888888889 +x_0=100000 +y_0=100000 +ellps=helmert +units=m";
+ case 2100 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=-199.87,74.79,246.62,0,0,0,0 +units=m";
+ case 2101 : return "+proj=lcc +lat_1=10.16666666666667 +lat_0=10.16666666666667 +lon_0=-71.60561777777777 +k_0=1 +x_0=0 +y_0=-52684.972 +ellps=intl +units=m";
+ case 2102 : return "+proj=lcc +lat_1=10.16666666666667 +lat_0=10.16666666666667 +lon_0=-71.60561777777777 +k_0=1 +x_0=200000 +y_0=147315.028 +ellps=intl +units=m";
+ case 2103 : return "+proj=lcc +lat_1=10.16666666666667 +lat_0=10.16666666666667 +lon_0=-71.60561777777777 +k_0=1 +x_0=500000 +y_0=447315.028 +ellps=intl +units=m";
+ case 2104 : return "+proj=lcc +lat_1=10.16666666666667 +lat_0=10.16666666666667 +lon_0=-71.60561777777777 +k_0=1 +x_0=-17044 +y_0=-23139.97 +ellps=intl +units=m";
+ case 2105 : return "+proj=tmerc +lat_0=-36.87972222222222 +lon_0=174.7641666666667 +k=0.9999 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2106 : return "+proj=tmerc +lat_0=-37.76111111111111 +lon_0=176.4661111111111 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2107 : return "+proj=tmerc +lat_0=-38.62444444444444 +lon_0=177.8855555555556 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2108 : return "+proj=tmerc +lat_0=-39.65083333333333 +lon_0=176.6736111111111 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2109 : return "+proj=tmerc +lat_0=-39.13555555555556 +lon_0=174.2277777777778 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2110 : return "+proj=tmerc +lat_0=-39.51222222222222 +lon_0=175.64 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2111 : return "+proj=tmerc +lat_0=-40.24194444444444 +lon_0=175.4880555555555 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2112 : return "+proj=tmerc +lat_0=-40.92527777777777 +lon_0=175.6472222222222 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2113 : return "+proj=tmerc +lat_0=-41.3011111111111 +lon_0=174.7763888888889 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2114 : return "+proj=tmerc +lat_0=-40.71472222222223 +lon_0=172.6719444444444 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2115 : return "+proj=tmerc +lat_0=-41.27444444444444 +lon_0=173.2991666666667 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2116 : return "+proj=tmerc +lat_0=-41.28972222222222 +lon_0=172.1088888888889 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2117 : return "+proj=tmerc +lat_0=-41.81055555555555 +lon_0=171.5811111111111 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2118 : return "+proj=tmerc +lat_0=-42.33361111111111 +lon_0=171.5497222222222 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2119 : return "+proj=tmerc +lat_0=-42.68888888888888 +lon_0=173.01 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2120 : return "+proj=tmerc +lat_0=-41.54444444444444 +lon_0=173.8019444444444 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2121 : return "+proj=tmerc +lat_0=-42.88611111111111 +lon_0=170.9797222222222 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2122 : return "+proj=tmerc +lat_0=-43.11 +lon_0=170.2608333333333 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2123 : return "+proj=tmerc +lat_0=-43.97777777777778 +lon_0=168.6061111111111 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2124 : return "+proj=tmerc +lat_0=-43.59055555555556 +lon_0=172.7269444444445 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2125 : return "+proj=tmerc +lat_0=-43.74861111111111 +lon_0=171.3605555555555 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2126 : return "+proj=tmerc +lat_0=-44.40194444444445 +lon_0=171.0572222222222 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2127 : return "+proj=tmerc +lat_0=-44.735 +lon_0=169.4675 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2128 : return "+proj=tmerc +lat_0=-45.13277777777778 +lon_0=168.3986111111111 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2129 : return "+proj=tmerc +lat_0=-45.56361111111111 +lon_0=167.7386111111111 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2130 : return "+proj=tmerc +lat_0=-45.81611111111111 +lon_0=170.6283333333333 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2131 : return "+proj=tmerc +lat_0=-45.86138888888889 +lon_0=170.2825 +k=0.99996 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2132 : return "+proj=tmerc +lat_0=-46.6 +lon_0=168.3427777777778 +k=1 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2133 : return "+proj=utm +zone=58 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2134 : return "+proj=utm +zone=59 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2135 : return "+proj=utm +zone=60 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2136 : return "+proj=tmerc +lat_0=4.666666666666667 +lon_0=-1 +k=0.99975 +x_0=274319.7391633579 +y_0=0 +a=6378300 +b=6356751.689189189 +towgs84=-199,32,322,0,0,0,0 +to_meter=0.3047997101815088";
+ case 2137 : return "+proj=tmerc +lat_0=0 +lon_0=-1 +k=0.9996 +x_0=500000 +y_0=0 +a=6378300 +b=6356751.689189189 +towgs84=-199,32,322,0,0,0,0 +units=m";
+ case 2138 : return "+proj=lcc +lat_1=60 +lat_2=46 +lat_0=44 +lon_0=-68.5 +x_0=0 +y_0=0 +ellps=clrk66 +units=m";
+ case 2139 : return "+proj=tmerc +lat_0=0 +lon_0=-55.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2140 : return "+proj=tmerc +lat_0=0 +lon_0=-58.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2141 : return "+proj=tmerc +lat_0=0 +lon_0=-61.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2142 : return "+proj=tmerc +lat_0=0 +lon_0=-64.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2143 : return "+proj=tmerc +lat_0=0 +lon_0=-67.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2144 : return "+proj=tmerc +lat_0=0 +lon_0=-70.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2145 : return "+proj=tmerc +lat_0=0 +lon_0=-73.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2146 : return "+proj=tmerc +lat_0=0 +lon_0=-76.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2147 : return "+proj=tmerc +lat_0=0 +lon_0=-79.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2148 : return "+proj=utm +zone=21 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2149 : return "+proj=utm +zone=18 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2150 : return "+proj=utm +zone=17 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2151 : return "+proj=utm +zone=13 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2152 : return "+proj=utm +zone=12 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2153 : return "+proj=utm +zone=11 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2154 : return "+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2155 : return "+proj=lcc +lat_1=-14.26666666666667 +lat_0=-14.26666666666667 +lon_0=170 +k_0=1 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +towgs84=-115,118,426,0,0,0,0 +to_meter=0.3048006096012192";
+ case 2156 : return "+proj=utm +zone=59 +south +ellps=GRS80 +units=m";
+ case 2157 : return "+proj=tmerc +lat_0=53.5 +lon_0=-8 +k=0.99982 +x_0=600000 +y_0=750000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2158 : return "+proj=utm +zone=29 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2159 : return "+proj=tmerc +lat_0=6.666666666666667 +lon_0=-12 +k=1 +x_0=152399.8550907544 +y_0=0 +a=6378300 +b=6356751.689189189 +to_meter=0.3047997101815088";
+ case 2160 : return "+proj=tmerc +lat_0=6.666666666666667 +lon_0=-12 +k=1 +x_0=243839.7681452071 +y_0=182879.8261089053 +a=6378300 +b=6356751.689189189 +to_meter=0.3047997101815088";
+ case 2161 : return "+proj=utm +zone=28 +ellps=clrk80 +towgs84=-88,4,101,0,0,0,0 +units=m";
+ case 2162 : return "+proj=utm +zone=29 +ellps=clrk80 +towgs84=-88,4,101,0,0,0,0 +units=m";
+ case 2163 : return "+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m";
+ case 2164 : return "+proj=tmerc +lat_0=0 +lon_0=-5 +k=0.9996 +x_0=500000 +y_0=0 +ellps=clrk80 +towgs84=-125,53,467,0,0,0,0 +units=m";
+ case 2165 : return "+proj=tmerc +lat_0=0 +lon_0=-5 +k=0.9996 +x_0=500000 +y_0=0 +ellps=clrk80 +towgs84=-124.76,53,466.79,0,0,0,0 +units=m";
+ case 2166 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0 +ellps=krass +towgs84=24,-123,-94,0.02,-0.25,-0.13,1.1 +units=m";
+ case 2167 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=krass +towgs84=24,-123,-94,0.02,-0.25,-0.13,1.1 +units=m";
+ case 2168 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=5500000 +y_0=0 +ellps=krass +towgs84=24,-123,-94,0.02,-0.25,-0.13,1.1 +units=m";
+ case 2169 : return "+proj=tmerc +lat_0=49.83333333333334 +lon_0=6.166666666666667 +k=1 +x_0=80000 +y_0=100000 +ellps=intl +towgs84=-193,13.7,-39.3,-0.41,-2.933,2.688,0.43 +units=m";
+ case 2170 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=0.9999 +x_0=500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 2171 : return "+proj=sterea +lat_0=50.625 +lon_0=21.08333333333333 +k=0.9998 +x_0=4637000 +y_0=5647000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 2172 : return "+proj=sterea +lat_0=53.00194444444445 +lon_0=21.50277777777778 +k=0.9998 +x_0=4603000 +y_0=5806000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 2173 : return "+proj=sterea +lat_0=53.58333333333334 +lon_0=17.00833333333333 +k=0.9998 +x_0=3501000 +y_0=5999000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 2174 : return "+proj=sterea +lat_0=51.67083333333333 +lon_0=16.67222222222222 +k=0.9998 +x_0=3703000 +y_0=5627000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 2175 : return "+proj=tmerc +lat_0=0 +lon_0=18.95833333333333 +k=0.999983 +x_0=237000 +y_0=-4700000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 2176 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=0.999923 +x_0=5500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2177 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=0.999923 +x_0=6500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2178 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=0.999923 +x_0=7500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2179 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.999923 +x_0=8500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2180 : return "+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +units=m";
+ case 2188 : return "+proj=utm +zone=25 +ellps=intl +units=m";
+ case 2189 : return "+proj=utm +zone=26 +ellps=intl +towgs84=-104,167,-38,0,0,0,0 +units=m";
+ case 2190 : return "+proj=utm +zone=26 +ellps=intl +towgs84=-203,141,53,0,0,0,0 +units=m";
+ case 2191 : return "+proj=utm +zone=28 +ellps=intl +units=m";
+ case 2192 : return "+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=2.337229166666667 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +ellps=intl +units=m";
+ case 2193 : return "+proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2194 : return "+proj=lcc +lat_1=-14.26666666666667 +lat_0=-14.26666666666667 +lon_0=-170 +k_0=1 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +towgs84=-115,118,426,0,0,0,0 +to_meter=0.3048006096012192";
+ case 2195 : return "+proj=utm +zone=2 +south +ellps=GRS80 +units=m";
+ case 2196 : return "+proj=tmerc +lat_0=0 +lon_0=9.5 +k=0.99995 +x_0=200000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2197 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=0.99995 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2198 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=900000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2199 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=4500000 +y_0=0 +ellps=krass +units=m";
+ case 2200 : return "+proj=sterea +lat_0=46.5 +lon_0=-66.5 +k=0.999912 +x_0=300000 +y_0=800000 +a=6378135 +b=6356750.304921594 +units=m";
+ case 2201 : return "+proj=utm +zone=18 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2202 : return "+proj=utm +zone=19 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2203 : return "+proj=utm +zone=20 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2204 : return "+proj=lcc +lat_1=35.25 +lat_2=36.41666666666666 +lat_0=34.66666666666666 +lon_0=-86 +x_0=609601.2192024384 +y_0=30480.06096012192 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 2205 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=38.96666666666667 +lat_0=37.5 +lon_0=-84.25 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 2206 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=9500000 +y_0=0 +ellps=intl +units=m";
+ case 2207 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=1 +x_0=10500000 +y_0=0 +ellps=intl +units=m";
+ case 2208 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=11500000 +y_0=0 +ellps=intl +units=m";
+ case 2209 : return "+proj=tmerc +lat_0=0 +lon_0=36 +k=1 +x_0=12500000 +y_0=0 +ellps=intl +units=m";
+ case 2210 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=13500000 +y_0=0 +ellps=intl +units=m";
+ case 2211 : return "+proj=tmerc +lat_0=0 +lon_0=42 +k=1 +x_0=14500000 +y_0=0 +ellps=intl +units=m";
+ case 2212 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=15500000 +y_0=0 +ellps=intl +units=m";
+ case 2213 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2214 : return "+proj=tmerc +lat_0=0 +lon_0=10.5 +k=0.999 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=-206.1,-174.7,-87.7,0,0,0,0 +units=m";
+ case 2215 : return "+proj=utm +zone=32 +a=6378249.2 +b=6356515 +towgs84=-70.9,-151.8,-41.4,0,0,0,0 +units=m";
+ case 2216 : return "+proj=utm +zone=22 +ellps=intl +units=m";
+ case 2217 : return "+proj=utm +zone=23 +ellps=intl +units=m";
+ case 2219 : return "+proj=utm +zone=19 +a=6378135 +b=6356750.304921594 +units=m";
+ case 2220 : return "+proj=utm +zone=20 +a=6378135 +b=6356750.304921594 +units=m";
+ case 2222 : return "+proj=tmerc +lat_0=31 +lon_0=-110.1666666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2223 : return "+proj=tmerc +lat_0=31 +lon_0=-111.9166666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2224 : return "+proj=tmerc +lat_0=31 +lon_0=-113.75 +k=0.999933333 +x_0=213360 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2225 : return "+proj=lcc +lat_1=41.66666666666666 +lat_2=40 +lat_0=39.33333333333334 +lon_0=-122 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2226 : return "+proj=lcc +lat_1=39.83333333333334 +lat_2=38.33333333333334 +lat_0=37.66666666666666 +lon_0=-122 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2227 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.06666666666667 +lat_0=36.5 +lon_0=-120.5 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2228 : return "+proj=lcc +lat_1=37.25 +lat_2=36 +lat_0=35.33333333333334 +lon_0=-119 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2229 : return "+proj=lcc +lat_1=35.46666666666667 +lat_2=34.03333333333333 +lat_0=33.5 +lon_0=-118 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2230 : return "+proj=lcc +lat_1=33.88333333333333 +lat_2=32.78333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2231 : return "+proj=lcc +lat_1=40.78333333333333 +lat_2=39.71666666666667 +lat_0=39.33333333333334 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2232 : return "+proj=lcc +lat_1=39.75 +lat_2=38.45 +lat_0=37.83333333333334 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2233 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.23333333333333 +lat_0=36.66666666666666 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2234 : return "+proj=lcc +lat_1=41.86666666666667 +lat_2=41.2 +lat_0=40.83333333333334 +lon_0=-72.75 +x_0=304800.6096012192 +y_0=152400.3048006096 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2235 : return "+proj=tmerc +lat_0=38 +lon_0=-75.41666666666667 +k=0.999995 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2236 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-81 +k=0.999941177 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2237 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-82 +k=0.999941177 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2238 : return "+proj=lcc +lat_1=30.75 +lat_2=29.58333333333333 +lat_0=29 +lon_0=-84.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2239 : return "+proj=tmerc +lat_0=30 +lon_0=-82.16666666666667 +k=0.9999 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2240 : return "+proj=tmerc +lat_0=30 +lon_0=-84.16666666666667 +k=0.9999 +x_0=699999.9998983998 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2241 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-112.1666666666667 +k=0.9999473679999999 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2242 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-114 +k=0.9999473679999999 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2243 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-115.75 +k=0.999933333 +x_0=800000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2244 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=99999.99989839978 +y_0=249364.9987299975 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2245 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=900000 +y_0=249364.9987299975 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2246 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=38.96666666666667 +lat_0=37.5 +lon_0=-84.25 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2247 : return "+proj=lcc +lat_1=37.93333333333333 +lat_2=36.73333333333333 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=500000.0001016001 +y_0=500000.0001016001 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2248 : return "+proj=lcc +lat_1=39.45 +lat_2=38.3 +lat_0=37.66666666666666 +lon_0=-77 +x_0=399999.9998983998 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2249 : return "+proj=lcc +lat_1=42.68333333333333 +lat_2=41.71666666666667 +lat_0=41 +lon_0=-71.5 +x_0=200000.0001016002 +y_0=750000 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2250 : return "+proj=lcc +lat_1=41.48333333333333 +lat_2=41.28333333333333 +lat_0=41 +lon_0=-70.5 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2251 : return "+proj=lcc +lat_1=47.08333333333334 +lat_2=45.48333333333333 +lat_0=44.78333333333333 +lon_0=-87 +x_0=7999999.999968001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2252 : return "+proj=lcc +lat_1=45.7 +lat_2=44.18333333333333 +lat_0=43.31666666666667 +lon_0=-84.36666666666666 +x_0=5999999.999976001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2253 : return "+proj=lcc +lat_1=43.66666666666666 +lat_2=42.1 +lat_0=41.5 +lon_0=-84.36666666666666 +x_0=3999999.999984 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2254 : return "+proj=tmerc +lat_0=29.5 +lon_0=-88.83333333333333 +k=0.99995 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2255 : return "+proj=tmerc +lat_0=29.5 +lon_0=-90.33333333333333 +k=0.99995 +x_0=699999.9998983998 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2256 : return "+proj=lcc +lat_1=49 +lat_2=45 +lat_0=44.25 +lon_0=-109.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2257 : return "+proj=tmerc +lat_0=31 +lon_0=-104.3333333333333 +k=0.999909091 +x_0=165000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2258 : return "+proj=tmerc +lat_0=31 +lon_0=-106.25 +k=0.9999 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2259 : return "+proj=tmerc +lat_0=31 +lon_0=-107.8333333333333 +k=0.999916667 +x_0=830000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2260 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2261 : return "+proj=tmerc +lat_0=40 +lon_0=-76.58333333333333 +k=0.9999375 +x_0=249999.9998983998 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2262 : return "+proj=tmerc +lat_0=40 +lon_0=-78.58333333333333 +k=0.9999375 +x_0=350000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2263 : return "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2264 : return "+proj=lcc +lat_1=36.16666666666666 +lat_2=34.33333333333334 +lat_0=33.75 +lon_0=-79 +x_0=609601.2192024384 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2265 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.43333333333333 +lat_0=47 +lon_0=-100.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2266 : return "+proj=lcc +lat_1=47.48333333333333 +lat_2=46.18333333333333 +lat_0=45.66666666666666 +lon_0=-100.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2267 : return "+proj=lcc +lat_1=36.76666666666667 +lat_2=35.56666666666667 +lat_0=35 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2268 : return "+proj=lcc +lat_1=35.23333333333333 +lat_2=33.93333333333333 +lat_0=33.33333333333334 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2269 : return "+proj=lcc +lat_1=46 +lat_2=44.33333333333334 +lat_0=43.66666666666666 +lon_0=-120.5 +x_0=2500000.0001424 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2270 : return "+proj=lcc +lat_1=44 +lat_2=42.33333333333334 +lat_0=41.66666666666666 +lon_0=-120.5 +x_0=1500000.0001464 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2271 : return "+proj=lcc +lat_1=41.95 +lat_2=40.88333333333333 +lat_0=40.16666666666666 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2272 : return "+proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2273 : return "+proj=lcc +lat_1=34.83333333333334 +lat_2=32.5 +lat_0=31.83333333333333 +lon_0=-81 +x_0=609600 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2274 : return "+proj=lcc +lat_1=36.41666666666666 +lat_2=35.25 +lat_0=34.33333333333334 +lon_0=-86 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2275 : return "+proj=lcc +lat_1=36.18333333333333 +lat_2=34.65 +lat_0=34 +lon_0=-101.5 +x_0=200000.0001016002 +y_0=999999.9998983998 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2276 : return "+proj=lcc +lat_1=33.96666666666667 +lat_2=32.13333333333333 +lat_0=31.66666666666667 +lon_0=-98.5 +x_0=600000 +y_0=2000000.0001016 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2277 : return "+proj=lcc +lat_1=31.88333333333333 +lat_2=30.11666666666667 +lat_0=29.66666666666667 +lon_0=-100.3333333333333 +x_0=699999.9998983998 +y_0=3000000 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2278 : return "+proj=lcc +lat_1=30.28333333333333 +lat_2=28.38333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=3999999.9998984 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2279 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.66666666666667 +lon_0=-98.5 +x_0=300000.0000000001 +y_0=5000000.0001016 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2280 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000.0001504 +y_0=999999.9999960001 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2281 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000.0001504 +y_0=1999999.999992 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2282 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000.0001504 +y_0=2999999.999988 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2283 : return "+proj=lcc +lat_1=39.2 +lat_2=38.03333333333333 +lat_0=37.66666666666666 +lon_0=-78.5 +x_0=3500000.0001016 +y_0=2000000.0001016 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2284 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=36.76666666666667 +lat_0=36.33333333333334 +lon_0=-78.5 +x_0=3500000.0001016 +y_0=999999.9998983998 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2285 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.5 +lat_0=47 +lon_0=-120.8333333333333 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2286 : return "+proj=lcc +lat_1=47.33333333333334 +lat_2=45.83333333333334 +lat_0=45.33333333333334 +lon_0=-120.5 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2287 : return "+proj=lcc +lat_1=46.76666666666667 +lat_2=45.56666666666667 +lat_0=45.16666666666666 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2288 : return "+proj=lcc +lat_1=45.5 +lat_2=44.25 +lat_0=43.83333333333334 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2289 : return "+proj=lcc +lat_1=44.06666666666667 +lat_2=42.73333333333333 +lat_0=42 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2290 : return "+proj=sterea +lat_0=47.25 +lon_0=-63 +k=0.999912 +x_0=700000 +y_0=400000 +a=6378135 +b=6356750.304921594 +units=m";
+ case 2291 : return "+proj=sterea +lat_0=47.25 +lon_0=-63 +k=0.999912 +x_0=400000 +y_0=800000 +a=6378135 +b=6356750.304921594 +units=m";
+ case 2292 : return "+proj=sterea +lat_0=47.25 +lon_0=-63 +k=0.999912 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2294 : return "+proj=tmerc +lat_0=0 +lon_0=-61.5 +k=0.9999 +x_0=4500000 +y_0=0 +a=6378135 +b=6356750.304921594 +units=m";
+ case 2295 : return "+proj=tmerc +lat_0=0 +lon_0=-64.5 +k=0.9999 +x_0=5500000 +y_0=0 +a=6378135 +b=6356750.304921594 +units=m";
+ case 2308 : return "+proj=tmerc +lat_0=0 +lon_0=109 +k=0.9996 +x_0=500000 +y_0=10000000 +ellps=bessel +units=m";
+ case 2309 : return "+proj=tmerc +lat_0=0 +lon_0=116 +k=0.9996 +x_0=500000 +y_0=10000000 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 2310 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=0.9996 +x_0=500000 +y_0=10000000 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 2311 : return "+proj=tmerc +lat_0=0 +lon_0=6 +k=0.9996 +x_0=500000 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 2312 : return "+proj=utm +zone=33 +ellps=clrk80 +units=m";
+ case 2313 : return "+proj=utm +zone=33 +ellps=clrk80 +units=m";
+ case 2314 : return "+proj=cass +lat_0=10.44166666666667 +lon_0=-61.33333333333334 +x_0=86501.46392052001 +y_0=65379.0134283 +a=6378293.645208759 +b=6356617.987679838 +to_meter=0.3047972654";
+ case 2315 : return "+proj=utm +zone=19 +south +ellps=intl +units=m";
+ case 2316 : return "+proj=utm +zone=20 +south +ellps=intl +units=m";
+ case 2317 : return "+proj=lcc +lat_1=9 +lat_2=3 +lat_0=6 +lon_0=-66 +x_0=1000000 +y_0=1000000 +ellps=intl +units=m";
+ case 2318 : return "+proj=lcc +lat_1=17 +lat_2=33 +lat_0=25.08951 +lon_0=48 +x_0=0 +y_0=0 +ellps=intl +units=m";
+ case 2319 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 2320 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=1 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 2321 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 2322 : return "+proj=tmerc +lat_0=0 +lon_0=36 +k=1 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 2323 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 2324 : return "+proj=tmerc +lat_0=0 +lon_0=42 +k=1 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 2325 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 2326 : return "+proj=tmerc +lat_0=22.31213333333334 +lon_0=114.1785555555556 +k=1 +x_0=836694.05 +y_0=819069.8 +ellps=intl +towgs84=-162.619,-276.959,-161.764,0.067753,-2.24365,-1.15883,-1.09425 +units=m";
+ case 2327 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=13500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2328 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=14500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2329 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=15500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2330 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=16500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2331 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=17500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2332 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=18500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2333 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=19500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2334 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=20500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2335 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=21500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2336 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=22500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2337 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=23500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2338 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2339 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2340 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2341 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2342 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2343 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2344 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2345 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2346 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2347 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2348 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2349 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=25500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2350 : return "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=26500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2351 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=27500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2352 : return "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=28500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2353 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=29500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2354 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=30500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2355 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=31500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2356 : return "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=32500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2357 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=33500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2358 : return "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=34500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2359 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=35500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2360 : return "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2361 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2362 : return "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2363 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2364 : return "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2365 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=41500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2366 : return "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=42500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2367 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=43500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2368 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=44500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2369 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=45500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2370 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2371 : return "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2372 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2373 : return "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2374 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2375 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2376 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2377 : return "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2378 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2379 : return "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2380 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2381 : return "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2382 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2383 : return "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2384 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2385 : return "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2386 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2387 : return "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2388 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2389 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2390 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +a=6378140 +b=6356755.288157528 +units=m";
+ case 2391 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=1500000 +y_0=0 +ellps=intl +towgs84=-96.0617,-82.4278,-121.743,4.80107,0.34543,-1.37646,1.4964 +units=m";
+ case 2392 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=1 +x_0=2500000 +y_0=0 +ellps=intl +towgs84=-96.0617,-82.4278,-121.743,4.80107,0.34543,-1.37646,1.4964 +units=m";
+ case 2393 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl +towgs84=-96.0617,-82.4278,-121.743,4.80107,0.34543,-1.37646,1.4964 +units=m";
+ case 2394 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=1 +x_0=4500000 +y_0=0 +ellps=intl +towgs84=-96.0617,-82.4278,-121.743,4.80107,0.34543,-1.37646,1.4964 +units=m";
+ case 2395 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=8500000 +y_0=0 +ellps=krass +towgs84=-76,-138,67,0,0,0,0 +units=m";
+ case 2396 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=9500000 +y_0=0 +ellps=krass +towgs84=-76,-138,67,0,0,0,0 +units=m";
+ case 2397 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0 +ellps=krass +towgs84=24,-123,-94,0.02,-0.25,-0.13,1.1 +units=m";
+ case 2398 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=krass +towgs84=24,-123,-94,0.02,-0.25,-0.13,1.1 +units=m";
+ case 2399 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=5500000 +y_0=0 +ellps=krass +towgs84=24,-123,-94,0.02,-0.25,-0.13,1.1 +units=m";
+ case 2400 : return "+proj=tmerc +lat_0=0 +lon_0=15.80827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 2401 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=25500000 +y_0=0 +ellps=krass +units=m";
+ case 2402 : return "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=26500000 +y_0=0 +ellps=krass +units=m";
+ case 2403 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=27500000 +y_0=0 +ellps=krass +units=m";
+ case 2404 : return "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=28500000 +y_0=0 +ellps=krass +units=m";
+ case 2405 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=29500000 +y_0=0 +ellps=krass +units=m";
+ case 2406 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=30500000 +y_0=0 +ellps=krass +units=m";
+ case 2407 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=31500000 +y_0=0 +ellps=krass +units=m";
+ case 2408 : return "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=32500000 +y_0=0 +ellps=krass +units=m";
+ case 2409 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=33500000 +y_0=0 +ellps=krass +units=m";
+ case 2410 : return "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=34500000 +y_0=0 +ellps=krass +units=m";
+ case 2411 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=35500000 +y_0=0 +ellps=krass +units=m";
+ case 2412 : return "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +ellps=krass +units=m";
+ case 2413 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=krass +units=m";
+ case 2414 : return "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +ellps=krass +units=m";
+ case 2415 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=krass +units=m";
+ case 2416 : return "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=krass +units=m";
+ case 2417 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=41500000 +y_0=0 +ellps=krass +units=m";
+ case 2418 : return "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=42500000 +y_0=0 +ellps=krass +units=m";
+ case 2419 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=43500000 +y_0=0 +ellps=krass +units=m";
+ case 2420 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=44500000 +y_0=0 +ellps=krass +units=m";
+ case 2421 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=45500000 +y_0=0 +ellps=krass +units=m";
+ case 2422 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2423 : return "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2424 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2425 : return "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2426 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2427 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2428 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2429 : return "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2430 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2431 : return "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2432 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2433 : return "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2434 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2435 : return "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2436 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2437 : return "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2438 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2439 : return "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2440 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2441 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2442 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2443 : return "+proj=tmerc +lat_0=33 +lon_0=129.5 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2444 : return "+proj=tmerc +lat_0=33 +lon_0=131 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2445 : return "+proj=tmerc +lat_0=36 +lon_0=132.1666666666667 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2446 : return "+proj=tmerc +lat_0=33 +lon_0=133.5 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2447 : return "+proj=tmerc +lat_0=36 +lon_0=134.3333333333333 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2448 : return "+proj=tmerc +lat_0=36 +lon_0=136 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2449 : return "+proj=tmerc +lat_0=36 +lon_0=137.1666666666667 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2450 : return "+proj=tmerc +lat_0=36 +lon_0=138.5 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2451 : return "+proj=tmerc +lat_0=36 +lon_0=139.8333333333333 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2452 : return "+proj=tmerc +lat_0=40 +lon_0=140.8333333333333 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2453 : return "+proj=tmerc +lat_0=44 +lon_0=140.25 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2454 : return "+proj=tmerc +lat_0=44 +lon_0=142.25 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2455 : return "+proj=tmerc +lat_0=44 +lon_0=144.25 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2456 : return "+proj=tmerc +lat_0=26 +lon_0=142 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2457 : return "+proj=tmerc +lat_0=26 +lon_0=127.5 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2458 : return "+proj=tmerc +lat_0=26 +lon_0=124 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2459 : return "+proj=tmerc +lat_0=26 +lon_0=131 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2460 : return "+proj=tmerc +lat_0=20 +lon_0=136 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2461 : return "+proj=tmerc +lat_0=26 +lon_0=154 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2462 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=4500000 +y_0=0 +ellps=krass +units=m";
+ case 2463 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2464 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2465 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2466 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2467 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2468 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2469 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2470 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2471 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2472 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2473 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2474 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2475 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2476 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2477 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2478 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2479 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2480 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2481 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2482 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2483 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2484 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2485 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2486 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2487 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2488 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2489 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2490 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2491 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2492 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2493 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2494 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2495 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2496 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2497 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2498 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2499 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2500 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2501 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2502 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2503 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2504 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2505 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2506 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2507 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2508 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2509 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2510 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2511 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2512 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2513 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2514 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2515 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2516 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2517 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2518 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2519 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2520 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2521 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2522 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2523 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=7500000 +y_0=0 +ellps=krass +units=m";
+ case 2524 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=1 +x_0=8500000 +y_0=0 +ellps=krass +units=m";
+ case 2525 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=9500000 +y_0=0 +ellps=krass +units=m";
+ case 2526 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=1 +x_0=10500000 +y_0=0 +ellps=krass +units=m";
+ case 2527 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=11500000 +y_0=0 +ellps=krass +units=m";
+ case 2528 : return "+proj=tmerc +lat_0=0 +lon_0=36 +k=1 +x_0=12500000 +y_0=0 +ellps=krass +units=m";
+ case 2529 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=13500000 +y_0=0 +ellps=krass +units=m";
+ case 2530 : return "+proj=tmerc +lat_0=0 +lon_0=42 +k=1 +x_0=14500000 +y_0=0 +ellps=krass +units=m";
+ case 2531 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=15500000 +y_0=0 +ellps=krass +units=m";
+ case 2532 : return "+proj=tmerc +lat_0=0 +lon_0=48 +k=1 +x_0=16500000 +y_0=0 +ellps=krass +units=m";
+ case 2533 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=17500000 +y_0=0 +ellps=krass +units=m";
+ case 2534 : return "+proj=tmerc +lat_0=0 +lon_0=54 +k=1 +x_0=18500000 +y_0=0 +ellps=krass +units=m";
+ case 2535 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=19500000 +y_0=0 +ellps=krass +units=m";
+ case 2536 : return "+proj=tmerc +lat_0=0 +lon_0=60 +k=1 +x_0=20500000 +y_0=0 +ellps=krass +units=m";
+ case 2537 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=21500000 +y_0=0 +ellps=krass +units=m";
+ case 2538 : return "+proj=tmerc +lat_0=0 +lon_0=66 +k=1 +x_0=22500000 +y_0=0 +ellps=krass +units=m";
+ case 2539 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=23500000 +y_0=0 +ellps=krass +units=m";
+ case 2540 : return "+proj=tmerc +lat_0=0 +lon_0=72 +k=1 +x_0=24500000 +y_0=0 +ellps=krass +units=m";
+ case 2541 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=25500000 +y_0=0 +ellps=krass +units=m";
+ case 2542 : return "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=26500000 +y_0=0 +ellps=krass +units=m";
+ case 2543 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=27500000 +y_0=0 +ellps=krass +units=m";
+ case 2544 : return "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=28500000 +y_0=0 +ellps=krass +units=m";
+ case 2545 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=29500000 +y_0=0 +ellps=krass +units=m";
+ case 2546 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=30500000 +y_0=0 +ellps=krass +units=m";
+ case 2547 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=31500000 +y_0=0 +ellps=krass +units=m";
+ case 2548 : return "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=32500000 +y_0=0 +ellps=krass +units=m";
+ case 2549 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=33500000 +y_0=0 +ellps=krass +units=m";
+ case 2550 : return "+proj=utm +zone=50 +south +ellps=bessel +towgs84=-404.78,685.68,45.47,0,0,0,0 +units=m";
+ case 2551 : return "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=34500000 +y_0=0 +ellps=krass +units=m";
+ case 2552 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=35500000 +y_0=0 +ellps=krass +units=m";
+ case 2553 : return "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +ellps=krass +units=m";
+ case 2554 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=krass +units=m";
+ case 2555 : return "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +ellps=krass +units=m";
+ case 2556 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=krass +units=m";
+ case 2557 : return "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=krass +units=m";
+ case 2558 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=41500000 +y_0=0 +ellps=krass +units=m";
+ case 2559 : return "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=42500000 +y_0=0 +ellps=krass +units=m";
+ case 2560 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=43500000 +y_0=0 +ellps=krass +units=m";
+ case 2561 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=44500000 +y_0=0 +ellps=krass +units=m";
+ case 2562 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=45500000 +y_0=0 +ellps=krass +units=m";
+ case 2563 : return "+proj=tmerc +lat_0=0 +lon_0=138 +k=1 +x_0=46500000 +y_0=0 +ellps=krass +units=m";
+ case 2564 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=47500000 +y_0=0 +ellps=krass +units=m";
+ case 2565 : return "+proj=tmerc +lat_0=0 +lon_0=144 +k=1 +x_0=48500000 +y_0=0 +ellps=krass +units=m";
+ case 2566 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=49500000 +y_0=0 +ellps=krass +units=m";
+ case 2567 : return "+proj=tmerc +lat_0=0 +lon_0=150 +k=1 +x_0=50500000 +y_0=0 +ellps=krass +units=m";
+ case 2568 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=51500000 +y_0=0 +ellps=krass +units=m";
+ case 2569 : return "+proj=tmerc +lat_0=0 +lon_0=156 +k=1 +x_0=52500000 +y_0=0 +ellps=krass +units=m";
+ case 2570 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=53500000 +y_0=0 +ellps=krass +units=m";
+ case 2571 : return "+proj=tmerc +lat_0=0 +lon_0=162 +k=1 +x_0=54500000 +y_0=0 +ellps=krass +units=m";
+ case 2572 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=55500000 +y_0=0 +ellps=krass +units=m";
+ case 2573 : return "+proj=tmerc +lat_0=0 +lon_0=168 +k=1 +x_0=56500000 +y_0=0 +ellps=krass +units=m";
+ case 2574 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=57500000 +y_0=0 +ellps=krass +units=m";
+ case 2575 : return "+proj=tmerc +lat_0=0 +lon_0=174 +k=1 +x_0=58500000 +y_0=0 +ellps=krass +units=m";
+ case 2576 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=59500000 +y_0=0 +ellps=krass +units=m";
+ case 2577 : return "+proj=tmerc +lat_0=0 +lon_0=180 +k=1 +x_0=60000000 +y_0=0 +ellps=krass +units=m";
+ case 2578 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=61500000 +y_0=0 +ellps=krass +units=m";
+ case 2579 : return "+proj=tmerc +lat_0=0 +lon_0=-174 +k=1 +x_0=62500000 +y_0=0 +ellps=krass +units=m";
+ case 2580 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=63500000 +y_0=0 +ellps=krass +units=m";
+ case 2581 : return "+proj=tmerc +lat_0=0 +lon_0=-168 +k=1 +x_0=64500000 +y_0=0 +ellps=krass +units=m";
+ case 2582 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2583 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2584 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2585 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2586 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2587 : return "+proj=tmerc +lat_0=0 +lon_0=36 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2588 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2589 : return "+proj=tmerc +lat_0=0 +lon_0=42 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2590 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2591 : return "+proj=tmerc +lat_0=0 +lon_0=48 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2592 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2593 : return "+proj=tmerc +lat_0=0 +lon_0=54 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2594 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2595 : return "+proj=tmerc +lat_0=0 +lon_0=60 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2596 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2597 : return "+proj=tmerc +lat_0=0 +lon_0=66 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2598 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2599 : return "+proj=tmerc +lat_0=0 +lon_0=72 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2600 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9998 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2601 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2602 : return "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2603 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2604 : return "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2605 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2606 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2607 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2608 : return "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2609 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2610 : return "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2611 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2612 : return "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2613 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2614 : return "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2615 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2616 : return "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2617 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2618 : return "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2619 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2620 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2621 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2622 : return "+proj=tmerc +lat_0=0 +lon_0=138 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2623 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2624 : return "+proj=tmerc +lat_0=0 +lon_0=144 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2625 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2626 : return "+proj=tmerc +lat_0=0 +lon_0=150 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2627 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2628 : return "+proj=tmerc +lat_0=0 +lon_0=156 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2629 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2630 : return "+proj=tmerc +lat_0=0 +lon_0=162 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2631 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2632 : return "+proj=tmerc +lat_0=0 +lon_0=168 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2633 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2634 : return "+proj=tmerc +lat_0=0 +lon_0=174 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2635 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2636 : return "+proj=tmerc +lat_0=0 +lon_0=180 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2637 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2638 : return "+proj=tmerc +lat_0=0 +lon_0=-174 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2639 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2640 : return "+proj=tmerc +lat_0=0 +lon_0=-168 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2641 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=7500000 +y_0=0 +ellps=krass +units=m";
+ case 2642 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=1 +x_0=8500000 +y_0=0 +ellps=krass +units=m";
+ case 2643 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=9500000 +y_0=0 +ellps=krass +units=m";
+ case 2644 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=1 +x_0=10500000 +y_0=0 +ellps=krass +units=m";
+ case 2645 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=11500000 +y_0=0 +ellps=krass +units=m";
+ case 2646 : return "+proj=tmerc +lat_0=0 +lon_0=36 +k=1 +x_0=12500000 +y_0=0 +ellps=krass +units=m";
+ case 2647 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=13500000 +y_0=0 +ellps=krass +units=m";
+ case 2648 : return "+proj=tmerc +lat_0=0 +lon_0=42 +k=1 +x_0=14500000 +y_0=0 +ellps=krass +units=m";
+ case 2649 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=15500000 +y_0=0 +ellps=krass +units=m";
+ case 2650 : return "+proj=tmerc +lat_0=0 +lon_0=48 +k=1 +x_0=16500000 +y_0=0 +ellps=krass +units=m";
+ case 2651 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=17500000 +y_0=0 +ellps=krass +units=m";
+ case 2652 : return "+proj=tmerc +lat_0=0 +lon_0=54 +k=1 +x_0=18500000 +y_0=0 +ellps=krass +units=m";
+ case 2653 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=19500000 +y_0=0 +ellps=krass +units=m";
+ case 2654 : return "+proj=tmerc +lat_0=0 +lon_0=60 +k=1 +x_0=20500000 +y_0=0 +ellps=krass +units=m";
+ case 2655 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=21500000 +y_0=0 +ellps=krass +units=m";
+ case 2656 : return "+proj=tmerc +lat_0=0 +lon_0=66 +k=1 +x_0=22500000 +y_0=0 +ellps=krass +units=m";
+ case 2657 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=23500000 +y_0=0 +ellps=krass +units=m";
+ case 2658 : return "+proj=tmerc +lat_0=0 +lon_0=72 +k=1 +x_0=24500000 +y_0=0 +ellps=krass +units=m";
+ case 2659 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=25500000 +y_0=0 +ellps=krass +units=m";
+ case 2660 : return "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=26500000 +y_0=0 +ellps=krass +units=m";
+ case 2661 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=27500000 +y_0=0 +ellps=krass +units=m";
+ case 2662 : return "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=28500000 +y_0=0 +ellps=krass +units=m";
+ case 2663 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=29500000 +y_0=0 +ellps=krass +units=m";
+ case 2664 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=30500000 +y_0=0 +ellps=krass +units=m";
+ case 2665 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=31500000 +y_0=0 +ellps=krass +units=m";
+ case 2666 : return "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=32500000 +y_0=0 +ellps=krass +units=m";
+ case 2667 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=33500000 +y_0=0 +ellps=krass +units=m";
+ case 2668 : return "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=34500000 +y_0=0 +ellps=krass +units=m";
+ case 2669 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=35500000 +y_0=0 +ellps=krass +units=m";
+ case 2670 : return "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +ellps=krass +units=m";
+ case 2671 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=krass +units=m";
+ case 2672 : return "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +ellps=krass +units=m";
+ case 2673 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=krass +units=m";
+ case 2674 : return "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=krass +units=m";
+ case 2675 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=41500000 +y_0=0 +ellps=krass +units=m";
+ case 2676 : return "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=42500000 +y_0=0 +ellps=krass +units=m";
+ case 2677 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=43500000 +y_0=0 +ellps=krass +units=m";
+ case 2678 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=44500000 +y_0=0 +ellps=krass +units=m";
+ case 2679 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=45500000 +y_0=0 +ellps=krass +units=m";
+ case 2680 : return "+proj=tmerc +lat_0=0 +lon_0=138 +k=1 +x_0=46500000 +y_0=0 +ellps=krass +units=m";
+ case 2681 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=47500000 +y_0=0 +ellps=krass +units=m";
+ case 2682 : return "+proj=tmerc +lat_0=0 +lon_0=144 +k=1 +x_0=48500000 +y_0=0 +ellps=krass +units=m";
+ case 2683 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=49500000 +y_0=0 +ellps=krass +units=m";
+ case 2684 : return "+proj=tmerc +lat_0=0 +lon_0=150 +k=1 +x_0=50500000 +y_0=0 +ellps=krass +units=m";
+ case 2685 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=51500000 +y_0=0 +ellps=krass +units=m";
+ case 2686 : return "+proj=tmerc +lat_0=0 +lon_0=156 +k=1 +x_0=52500000 +y_0=0 +ellps=krass +units=m";
+ case 2687 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=53500000 +y_0=0 +ellps=krass +units=m";
+ case 2688 : return "+proj=tmerc +lat_0=0 +lon_0=162 +k=1 +x_0=54500000 +y_0=0 +ellps=krass +units=m";
+ case 2689 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=55500000 +y_0=0 +ellps=krass +units=m";
+ case 2690 : return "+proj=tmerc +lat_0=0 +lon_0=168 +k=1 +x_0=56500000 +y_0=0 +ellps=krass +units=m";
+ case 2691 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=57500000 +y_0=0 +ellps=krass +units=m";
+ case 2692 : return "+proj=tmerc +lat_0=0 +lon_0=174 +k=1 +x_0=58500000 +y_0=0 +ellps=krass +units=m";
+ case 2693 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=59500000 +y_0=0 +ellps=krass +units=m";
+ case 2694 : return "+proj=tmerc +lat_0=0 +lon_0=180 +k=1 +x_0=60000000 +y_0=0 +ellps=krass +units=m";
+ case 2695 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=61500000 +y_0=0 +ellps=krass +units=m";
+ case 2696 : return "+proj=tmerc +lat_0=0 +lon_0=-174 +k=1 +x_0=62500000 +y_0=0 +ellps=krass +units=m";
+ case 2697 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=63500000 +y_0=0 +ellps=krass +units=m";
+ case 2698 : return "+proj=tmerc +lat_0=0 +lon_0=-168 +k=1 +x_0=64500000 +y_0=0 +ellps=krass +units=m";
+ case 2699 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2700 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2701 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2702 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2703 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2704 : return "+proj=tmerc +lat_0=0 +lon_0=36 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2705 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2706 : return "+proj=tmerc +lat_0=0 +lon_0=42 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2707 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2708 : return "+proj=tmerc +lat_0=0 +lon_0=48 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2709 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2710 : return "+proj=tmerc +lat_0=0 +lon_0=54 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2711 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2712 : return "+proj=tmerc +lat_0=0 +lon_0=60 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2713 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2714 : return "+proj=tmerc +lat_0=0 +lon_0=66 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2715 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2716 : return "+proj=tmerc +lat_0=0 +lon_0=72 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2717 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2718 : return "+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2719 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2720 : return "+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2721 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2722 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2723 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2724 : return "+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2725 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2726 : return "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2727 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2728 : return "+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2729 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2730 : return "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2731 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2732 : return "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2733 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2734 : return "+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2735 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2736 : return "+proj=utm +zone=36 +south +ellps=clrk66 +units=m";
+ case 2737 : return "+proj=utm +zone=37 +south +ellps=clrk66 +units=m";
+ case 2738 : return "+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2739 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2740 : return "+proj=tmerc +lat_0=0 +lon_0=138 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2741 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2742 : return "+proj=tmerc +lat_0=0 +lon_0=144 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2743 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2744 : return "+proj=tmerc +lat_0=0 +lon_0=150 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2745 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2746 : return "+proj=tmerc +lat_0=0 +lon_0=156 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2747 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2748 : return "+proj=tmerc +lat_0=0 +lon_0=162 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2749 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2750 : return "+proj=tmerc +lat_0=0 +lon_0=168 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2751 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2752 : return "+proj=tmerc +lat_0=0 +lon_0=174 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2753 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2754 : return "+proj=tmerc +lat_0=0 +lon_0=180 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2755 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2756 : return "+proj=tmerc +lat_0=0 +lon_0=-174 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2757 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2758 : return "+proj=tmerc +lat_0=0 +lon_0=-168 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 2759 : return "+proj=tmerc +lat_0=30.5 +lon_0=-85.83333333333333 +k=0.99996 +x_0=200000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2760 : return "+proj=tmerc +lat_0=30 +lon_0=-87.5 +k=0.999933333 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2761 : return "+proj=tmerc +lat_0=31 +lon_0=-110.1666666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +units=m";
+ case 2762 : return "+proj=tmerc +lat_0=31 +lon_0=-111.9166666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +units=m";
+ case 2763 : return "+proj=tmerc +lat_0=31 +lon_0=-113.75 +k=0.999933333 +x_0=213360 +y_0=0 +ellps=GRS80 +units=m";
+ case 2764 : return "+proj=lcc +lat_1=36.23333333333333 +lat_2=34.93333333333333 +lat_0=34.33333333333334 +lon_0=-92 +x_0=400000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2765 : return "+proj=lcc +lat_1=34.76666666666667 +lat_2=33.3 +lat_0=32.66666666666666 +lon_0=-92 +x_0=400000 +y_0=400000 +ellps=GRS80 +units=m";
+ case 2766 : return "+proj=lcc +lat_1=41.66666666666666 +lat_2=40 +lat_0=39.33333333333334 +lon_0=-122 +x_0=2000000 +y_0=500000 +ellps=GRS80 +units=m";
+ case 2767 : return "+proj=lcc +lat_1=39.83333333333334 +lat_2=38.33333333333334 +lat_0=37.66666666666666 +lon_0=-122 +x_0=2000000 +y_0=500000 +ellps=GRS80 +units=m";
+ case 2768 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.06666666666667 +lat_0=36.5 +lon_0=-120.5 +x_0=2000000 +y_0=500000 +ellps=GRS80 +units=m";
+ case 2769 : return "+proj=lcc +lat_1=37.25 +lat_2=36 +lat_0=35.33333333333334 +lon_0=-119 +x_0=2000000 +y_0=500000 +ellps=GRS80 +units=m";
+ case 2770 : return "+proj=lcc +lat_1=35.46666666666667 +lat_2=34.03333333333333 +lat_0=33.5 +lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 +units=m";
+ case 2771 : return "+proj=lcc +lat_1=33.88333333333333 +lat_2=32.78333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=2000000 +y_0=500000 +ellps=GRS80 +units=m";
+ case 2772 : return "+proj=lcc +lat_1=40.78333333333333 +lat_2=39.71666666666667 +lat_0=39.33333333333334 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +units=m";
+ case 2773 : return "+proj=lcc +lat_1=39.75 +lat_2=38.45 +lat_0=37.83333333333334 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +units=m";
+ case 2774 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.23333333333333 +lat_0=36.66666666666666 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +units=m";
+ case 2775 : return "+proj=lcc +lat_1=41.86666666666667 +lat_2=41.2 +lat_0=40.83333333333334 +lon_0=-72.75 +x_0=304800.6096 +y_0=152400.3048 +ellps=GRS80 +units=m";
+ case 2776 : return "+proj=tmerc +lat_0=38 +lon_0=-75.41666666666667 +k=0.999995 +x_0=200000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2777 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-81 +k=0.999941177 +x_0=200000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2778 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-82 +k=0.999941177 +x_0=200000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2779 : return "+proj=lcc +lat_1=30.75 +lat_2=29.58333333333333 +lat_0=29 +lon_0=-84.5 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2780 : return "+proj=tmerc +lat_0=30 +lon_0=-82.16666666666667 +k=0.9999 +x_0=200000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2781 : return "+proj=tmerc +lat_0=30 +lon_0=-84.16666666666667 +k=0.9999 +x_0=700000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2782 : return "+proj=tmerc +lat_0=18.83333333333333 +lon_0=-155.5 +k=0.999966667 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2783 : return "+proj=tmerc +lat_0=20.33333333333333 +lon_0=-156.6666666666667 +k=0.999966667 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2784 : return "+proj=tmerc +lat_0=21.16666666666667 +lon_0=-158 +k=0.99999 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2785 : return "+proj=tmerc +lat_0=21.83333333333333 +lon_0=-159.5 +k=0.99999 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2786 : return "+proj=tmerc +lat_0=21.66666666666667 +lon_0=-160.1666666666667 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2787 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-112.1666666666667 +k=0.9999473679999999 +x_0=200000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2788 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-114 +k=0.9999473679999999 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2789 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-115.75 +k=0.999933333 +x_0=800000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2790 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-88.33333333333333 +k=0.9999749999999999 +x_0=300000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2791 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-90.16666666666667 +k=0.999941177 +x_0=700000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2792 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=100000 +y_0=250000 +ellps=GRS80 +units=m";
+ case 2793 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=900000 +y_0=250000 +ellps=GRS80 +units=m";
+ case 2794 : return "+proj=lcc +lat_1=43.26666666666667 +lat_2=42.06666666666667 +lat_0=41.5 +lon_0=-93.5 +x_0=1500000 +y_0=1000000 +ellps=GRS80 +units=m";
+ case 2795 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.61666666666667 +lat_0=40 +lon_0=-93.5 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2796 : return "+proj=lcc +lat_1=39.78333333333333 +lat_2=38.71666666666667 +lat_0=38.33333333333334 +lon_0=-98 +x_0=400000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2797 : return "+proj=lcc +lat_1=38.56666666666667 +lat_2=37.26666666666667 +lat_0=36.66666666666666 +lon_0=-98.5 +x_0=400000 +y_0=400000 +ellps=GRS80 +units=m";
+ case 2798 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=38.96666666666667 +lat_0=37.5 +lon_0=-84.25 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2799 : return "+proj=lcc +lat_1=37.93333333333333 +lat_2=36.73333333333333 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=500000 +y_0=500000 +ellps=GRS80 +units=m";
+ case 2800 : return "+proj=lcc +lat_1=32.66666666666666 +lat_2=31.16666666666667 +lat_0=30.5 +lon_0=-92.5 +x_0=1000000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2801 : return "+proj=lcc +lat_1=30.7 +lat_2=29.3 +lat_0=28.5 +lon_0=-91.33333333333333 +x_0=1000000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2802 : return "+proj=tmerc +lat_0=43.66666666666666 +lon_0=-68.5 +k=0.9999 +x_0=300000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2803 : return "+proj=tmerc +lat_0=42.83333333333334 +lon_0=-70.16666666666667 +k=0.999966667 +x_0=900000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2804 : return "+proj=lcc +lat_1=39.45 +lat_2=38.3 +lat_0=37.66666666666666 +lon_0=-77 +x_0=400000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2805 : return "+proj=lcc +lat_1=42.68333333333333 +lat_2=41.71666666666667 +lat_0=41 +lon_0=-71.5 +x_0=200000 +y_0=750000 +ellps=GRS80 +units=m";
+ case 2806 : return "+proj=lcc +lat_1=41.48333333333333 +lat_2=41.28333333333333 +lat_0=41 +lon_0=-70.5 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2807 : return "+proj=lcc +lat_1=47.08333333333334 +lat_2=45.48333333333333 +lat_0=44.78333333333333 +lon_0=-87 +x_0=8000000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2808 : return "+proj=lcc +lat_1=45.7 +lat_2=44.18333333333333 +lat_0=43.31666666666667 +lon_0=-84.36666666666666 +x_0=6000000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2809 : return "+proj=lcc +lat_1=43.66666666666666 +lat_2=42.1 +lat_0=41.5 +lon_0=-84.36666666666666 +x_0=4000000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2810 : return "+proj=lcc +lat_1=48.63333333333333 +lat_2=47.03333333333333 +lat_0=46.5 +lon_0=-93.09999999999999 +x_0=800000 +y_0=100000 +ellps=GRS80 +units=m";
+ case 2811 : return "+proj=lcc +lat_1=47.05 +lat_2=45.61666666666667 +lat_0=45 +lon_0=-94.25 +x_0=800000 +y_0=100000 +ellps=GRS80 +units=m";
+ case 2812 : return "+proj=lcc +lat_1=45.21666666666667 +lat_2=43.78333333333333 +lat_0=43 +lon_0=-94 +x_0=800000 +y_0=100000 +ellps=GRS80 +units=m";
+ case 2813 : return "+proj=tmerc +lat_0=29.5 +lon_0=-88.83333333333333 +k=0.99995 +x_0=300000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2814 : return "+proj=tmerc +lat_0=29.5 +lon_0=-90.33333333333333 +k=0.99995 +x_0=700000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2815 : return "+proj=tmerc +lat_0=35.83333333333334 +lon_0=-90.5 +k=0.999933333 +x_0=250000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2816 : return "+proj=tmerc +lat_0=35.83333333333334 +lon_0=-92.5 +k=0.999933333 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2817 : return "+proj=tmerc +lat_0=36.16666666666666 +lon_0=-94.5 +k=0.999941177 +x_0=850000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2818 : return "+proj=lcc +lat_1=49 +lat_2=45 +lat_0=44.25 +lon_0=-109.5 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2819 : return "+proj=lcc +lat_1=43 +lat_2=40 +lat_0=39.83333333333334 +lon_0=-100 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2820 : return "+proj=tmerc +lat_0=34.75 +lon_0=-115.5833333333333 +k=0.9999 +x_0=200000 +y_0=8000000 +ellps=GRS80 +units=m";
+ case 2821 : return "+proj=tmerc +lat_0=34.75 +lon_0=-116.6666666666667 +k=0.9999 +x_0=500000 +y_0=6000000 +ellps=GRS80 +units=m";
+ case 2822 : return "+proj=tmerc +lat_0=34.75 +lon_0=-118.5833333333333 +k=0.9999 +x_0=800000 +y_0=4000000 +ellps=GRS80 +units=m";
+ case 2823 : return "+proj=tmerc +lat_0=42.5 +lon_0=-71.66666666666667 +k=0.999966667 +x_0=300000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2824 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2825 : return "+proj=tmerc +lat_0=31 +lon_0=-104.3333333333333 +k=0.999909091 +x_0=165000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2826 : return "+proj=tmerc +lat_0=31 +lon_0=-106.25 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2827 : return "+proj=tmerc +lat_0=31 +lon_0=-107.8333333333333 +k=0.999916667 +x_0=830000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2828 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2829 : return "+proj=tmerc +lat_0=40 +lon_0=-76.58333333333333 +k=0.9999375 +x_0=250000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2830 : return "+proj=tmerc +lat_0=40 +lon_0=-78.58333333333333 +k=0.9999375 +x_0=350000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2831 : return "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2832 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.43333333333333 +lat_0=47 +lon_0=-100.5 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2833 : return "+proj=lcc +lat_1=47.48333333333333 +lat_2=46.18333333333333 +lat_0=45.66666666666666 +lon_0=-100.5 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2834 : return "+proj=lcc +lat_1=41.7 +lat_2=40.43333333333333 +lat_0=39.66666666666666 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2835 : return "+proj=lcc +lat_1=40.03333333333333 +lat_2=38.73333333333333 +lat_0=38 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2836 : return "+proj=lcc +lat_1=36.76666666666667 +lat_2=35.56666666666667 +lat_0=35 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2837 : return "+proj=lcc +lat_1=35.23333333333333 +lat_2=33.93333333333333 +lat_0=33.33333333333334 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2838 : return "+proj=lcc +lat_1=46 +lat_2=44.33333333333334 +lat_0=43.66666666666666 +lon_0=-120.5 +x_0=2500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2839 : return "+proj=lcc +lat_1=44 +lat_2=42.33333333333334 +lat_0=41.66666666666666 +lon_0=-120.5 +x_0=1500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2840 : return "+proj=tmerc +lat_0=41.08333333333334 +lon_0=-71.5 +k=0.99999375 +x_0=100000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2841 : return "+proj=lcc +lat_1=45.68333333333333 +lat_2=44.41666666666666 +lat_0=43.83333333333334 +lon_0=-100 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2842 : return "+proj=lcc +lat_1=44.4 +lat_2=42.83333333333334 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2843 : return "+proj=lcc +lat_1=36.41666666666666 +lat_2=35.25 +lat_0=34.33333333333334 +lon_0=-86 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2844 : return "+proj=lcc +lat_1=36.18333333333333 +lat_2=34.65 +lat_0=34 +lon_0=-101.5 +x_0=200000 +y_0=1000000 +ellps=GRS80 +units=m";
+ case 2845 : return "+proj=lcc +lat_1=33.96666666666667 +lat_2=32.13333333333333 +lat_0=31.66666666666667 +lon_0=-98.5 +x_0=600000 +y_0=2000000 +ellps=GRS80 +units=m";
+ case 2846 : return "+proj=lcc +lat_1=31.88333333333333 +lat_2=30.11666666666667 +lat_0=29.66666666666667 +lon_0=-100.3333333333333 +x_0=700000 +y_0=3000000 +ellps=GRS80 +units=m";
+ case 2847 : return "+proj=lcc +lat_1=30.28333333333333 +lat_2=28.38333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=4000000 +ellps=GRS80 +units=m";
+ case 2848 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.66666666666667 +lon_0=-98.5 +x_0=300000 +y_0=5000000 +ellps=GRS80 +units=m";
+ case 2849 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000 +y_0=1000000 +ellps=GRS80 +units=m";
+ case 2850 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000 +y_0=2000000 +ellps=GRS80 +units=m";
+ case 2851 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000 +y_0=3000000 +ellps=GRS80 +units=m";
+ case 2852 : return "+proj=tmerc +lat_0=42.5 +lon_0=-72.5 +k=0.999964286 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2853 : return "+proj=lcc +lat_1=39.2 +lat_2=38.03333333333333 +lat_0=37.66666666666666 +lon_0=-78.5 +x_0=3500000 +y_0=2000000 +ellps=GRS80 +units=m";
+ case 2854 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=36.76666666666667 +lat_0=36.33333333333334 +lon_0=-78.5 +x_0=3500000 +y_0=1000000 +ellps=GRS80 +units=m";
+ case 2855 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.5 +lat_0=47 +lon_0=-120.8333333333333 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2856 : return "+proj=lcc +lat_1=47.33333333333334 +lat_2=45.83333333333334 +lat_0=45.33333333333334 +lon_0=-120.5 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2857 : return "+proj=lcc +lat_1=40.25 +lat_2=39 +lat_0=38.5 +lon_0=-79.5 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2858 : return "+proj=lcc +lat_1=38.88333333333333 +lat_2=37.48333333333333 +lat_0=37 +lon_0=-81 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2859 : return "+proj=lcc +lat_1=46.76666666666667 +lat_2=45.56666666666667 +lat_0=45.16666666666666 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2860 : return "+proj=lcc +lat_1=45.5 +lat_2=44.25 +lat_0=43.83333333333334 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2861 : return "+proj=lcc +lat_1=44.06666666666667 +lat_2=42.73333333333333 +lat_0=42 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2862 : return "+proj=tmerc +lat_0=40.5 +lon_0=-105.1666666666667 +k=0.9999375 +x_0=200000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2863 : return "+proj=tmerc +lat_0=40.5 +lon_0=-107.3333333333333 +k=0.9999375 +x_0=400000 +y_0=100000 +ellps=GRS80 +units=m";
+ case 2864 : return "+proj=tmerc +lat_0=40.5 +lon_0=-108.75 +k=0.9999375 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2865 : return "+proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +k=0.9999375 +x_0=800000 +y_0=100000 +ellps=GRS80 +units=m";
+ case 2866 : return "+proj=lcc +lat_1=18.43333333333333 +lat_2=18.03333333333333 +lat_0=17.83333333333333 +lon_0=-66.43333333333334 +x_0=200000 +y_0=200000 +ellps=GRS80 +units=m";
+ case 2867 : return "+proj=tmerc +lat_0=31 +lon_0=-110.1666666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2868 : return "+proj=tmerc +lat_0=31 +lon_0=-111.9166666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2869 : return "+proj=tmerc +lat_0=31 +lon_0=-113.75 +k=0.999933333 +x_0=213360 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2870 : return "+proj=lcc +lat_1=41.66666666666666 +lat_2=40 +lat_0=39.33333333333334 +lon_0=-122 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2871 : return "+proj=lcc +lat_1=39.83333333333334 +lat_2=38.33333333333334 +lat_0=37.66666666666666 +lon_0=-122 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2872 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.06666666666667 +lat_0=36.5 +lon_0=-120.5 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2873 : return "+proj=lcc +lat_1=37.25 +lat_2=36 +lat_0=35.33333333333334 +lon_0=-119 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2874 : return "+proj=lcc +lat_1=35.46666666666667 +lat_2=34.03333333333333 +lat_0=33.5 +lon_0=-118 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2875 : return "+proj=lcc +lat_1=33.88333333333333 +lat_2=32.78333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2876 : return "+proj=lcc +lat_1=40.78333333333333 +lat_2=39.71666666666667 +lat_0=39.33333333333334 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2877 : return "+proj=lcc +lat_1=39.75 +lat_2=38.45 +lat_0=37.83333333333334 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2878 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.23333333333333 +lat_0=36.66666666666666 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2879 : return "+proj=lcc +lat_1=41.86666666666667 +lat_2=41.2 +lat_0=40.83333333333334 +lon_0=-72.75 +x_0=304800.6096012192 +y_0=152400.3048006096 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2880 : return "+proj=tmerc +lat_0=38 +lon_0=-75.41666666666667 +k=0.999995 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2881 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-81 +k=0.999941177 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2882 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-82 +k=0.999941177 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2883 : return "+proj=lcc +lat_1=30.75 +lat_2=29.58333333333333 +lat_0=29 +lon_0=-84.5 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2884 : return "+proj=tmerc +lat_0=30 +lon_0=-82.16666666666667 +k=0.9999 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2885 : return "+proj=tmerc +lat_0=30 +lon_0=-84.16666666666667 +k=0.9999 +x_0=699999.9998983998 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2886 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-112.1666666666667 +k=0.9999473679999999 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2887 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-114 +k=0.9999473679999999 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2888 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-115.75 +k=0.999933333 +x_0=800000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2889 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=99999.99989839978 +y_0=249364.9987299975 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2890 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=900000 +y_0=249364.9987299975 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2891 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=38.96666666666667 +lat_0=37.5 +lon_0=-84.25 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2892 : return "+proj=lcc +lat_1=37.93333333333333 +lat_2=36.73333333333333 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=500000.0001016001 +y_0=500000.0001016001 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2893 : return "+proj=lcc +lat_1=39.45 +lat_2=38.3 +lat_0=37.66666666666666 +lon_0=-77 +x_0=399999.9998983998 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2894 : return "+proj=lcc +lat_1=42.68333333333333 +lat_2=41.71666666666667 +lat_0=41 +lon_0=-71.5 +x_0=200000.0001016002 +y_0=750000 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2895 : return "+proj=lcc +lat_1=41.48333333333333 +lat_2=41.28333333333333 +lat_0=41 +lon_0=-70.5 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2896 : return "+proj=lcc +lat_1=47.08333333333334 +lat_2=45.48333333333333 +lat_0=44.78333333333333 +lon_0=-87 +x_0=7999999.999968001 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2897 : return "+proj=lcc +lat_1=45.7 +lat_2=44.18333333333333 +lat_0=43.31666666666667 +lon_0=-84.36666666666666 +x_0=5999999.999976001 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2898 : return "+proj=lcc +lat_1=43.66666666666666 +lat_2=42.1 +lat_0=41.5 +lon_0=-84.36666666666666 +x_0=3999999.999984 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2899 : return "+proj=tmerc +lat_0=29.5 +lon_0=-88.83333333333333 +k=0.99995 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2900 : return "+proj=tmerc +lat_0=29.5 +lon_0=-90.33333333333333 +k=0.99995 +x_0=699999.9998983998 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2901 : return "+proj=lcc +lat_1=49 +lat_2=45 +lat_0=44.25 +lon_0=-109.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2902 : return "+proj=tmerc +lat_0=31 +lon_0=-104.3333333333333 +k=0.999909091 +x_0=165000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2903 : return "+proj=tmerc +lat_0=31 +lon_0=-106.25 +k=0.9999 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2904 : return "+proj=tmerc +lat_0=31 +lon_0=-107.8333333333333 +k=0.999916667 +x_0=830000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2905 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2906 : return "+proj=tmerc +lat_0=40 +lon_0=-76.58333333333333 +k=0.9999375 +x_0=249999.9998983998 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2907 : return "+proj=tmerc +lat_0=40 +lon_0=-78.58333333333333 +k=0.9999375 +x_0=350000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2908 : return "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2909 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.43333333333333 +lat_0=47 +lon_0=-100.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2910 : return "+proj=lcc +lat_1=47.48333333333333 +lat_2=46.18333333333333 +lat_0=45.66666666666666 +lon_0=-100.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2911 : return "+proj=lcc +lat_1=36.76666666666667 +lat_2=35.56666666666667 +lat_0=35 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2912 : return "+proj=lcc +lat_1=35.23333333333333 +lat_2=33.93333333333333 +lat_0=33.33333333333334 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2913 : return "+proj=lcc +lat_1=46 +lat_2=44.33333333333334 +lat_0=43.66666666666666 +lon_0=-120.5 +x_0=2500000.0001424 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2914 : return "+proj=lcc +lat_1=44 +lat_2=42.33333333333334 +lat_0=41.66666666666666 +lon_0=-120.5 +x_0=1500000.0001464 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2915 : return "+proj=lcc +lat_1=36.41666666666666 +lat_2=35.25 +lat_0=34.33333333333334 +lon_0=-86 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2916 : return "+proj=lcc +lat_1=36.18333333333333 +lat_2=34.65 +lat_0=34 +lon_0=-101.5 +x_0=200000.0001016002 +y_0=999999.9998983998 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2917 : return "+proj=lcc +lat_1=33.96666666666667 +lat_2=32.13333333333333 +lat_0=31.66666666666667 +lon_0=-98.5 +x_0=600000 +y_0=2000000.0001016 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2918 : return "+proj=lcc +lat_1=31.88333333333333 +lat_2=30.11666666666667 +lat_0=29.66666666666667 +lon_0=-100.3333333333333 +x_0=699999.9998983998 +y_0=3000000 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2919 : return "+proj=lcc +lat_1=30.28333333333333 +lat_2=28.38333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=3999999.9998984 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2920 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.66666666666667 +lon_0=-98.5 +x_0=300000.0000000001 +y_0=5000000.0001016 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2921 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000.0001504 +y_0=999999.9999960001 +ellps=GRS80 +to_meter=0.3048";
+ case 2922 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000.0001504 +y_0=1999999.999992 +ellps=GRS80 +to_meter=0.3048";
+ case 2923 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000.0001504 +y_0=2999999.999988 +ellps=GRS80 +to_meter=0.3048";
+ case 2924 : return "+proj=lcc +lat_1=39.2 +lat_2=38.03333333333333 +lat_0=37.66666666666666 +lon_0=-78.5 +x_0=3500000.0001016 +y_0=2000000.0001016 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2925 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=36.76666666666667 +lat_0=36.33333333333334 +lon_0=-78.5 +x_0=3500000.0001016 +y_0=999999.9998983998 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2926 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.5 +lat_0=47 +lon_0=-120.8333333333333 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2927 : return "+proj=lcc +lat_1=47.33333333333334 +lat_2=45.83333333333334 +lat_0=45.33333333333334 +lon_0=-120.5 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2928 : return "+proj=lcc +lat_1=46.76666666666667 +lat_2=45.56666666666667 +lat_0=45.16666666666666 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2929 : return "+proj=lcc +lat_1=45.5 +lat_2=44.25 +lat_0=43.83333333333334 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2930 : return "+proj=lcc +lat_1=44.06666666666667 +lat_2=42.73333333333333 +lat_0=42 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2931 : return "+proj=tmerc +lat_0=0 +lon_0=13 +k=0.9996 +x_0=500000 +y_0=0 +a=6378249.2 +b=6356515 +towgs84=-106,-87,188,0,0,0,0 +units=m";
+ case 2932 : return "+proj=tmerc +lat_0=24.45 +lon_0=51.21666666666667 +k=0.99999 +x_0=200000 +y_0=300000 +ellps=intl +towgs84=-119.425,-303.659,-11.0006,1.1643,0.174458,1.09626,3.65706 +units=m";
+ case 2933 : return "+proj=utm +zone=50 +south +ellps=bessel +units=m";
+ case 2934 : return "+proj=merc +lon_0=110 +k=0.997 +x_0=3900000 +y_0=900000 +ellps=bessel +pm=jakarta +units=m";
+ case 2935 : return "+proj=tmerc +lat_0=0.1166666666666667 +lon_0=41.53333333333333 +k=1 +x_0=1300000 +y_0=0 +ellps=krass +units=m";
+ case 2936 : return "+proj=tmerc +lat_0=0.1166666666666667 +lon_0=44.53333333333333 +k=1 +x_0=2300000 +y_0=0 +ellps=krass +units=m";
+ case 2937 : return "+proj=tmerc +lat_0=0.1166666666666667 +lon_0=47.53333333333333 +k=1 +x_0=3300000 +y_0=0 +ellps=krass +units=m";
+ case 2938 : return "+proj=tmerc +lat_0=0.1166666666666667 +lon_0=50.53333333333333 +k=1 +x_0=4300000 +y_0=0 +ellps=krass +units=m";
+ case 2939 : return "+proj=tmerc +lat_0=0.1333333333333333 +lon_0=50.76666666666667 +k=1 +x_0=2300000 +y_0=0 +ellps=krass +units=m";
+ case 2940 : return "+proj=tmerc +lat_0=0.1333333333333333 +lon_0=53.76666666666667 +k=1 +x_0=3300000 +y_0=0 +ellps=krass +units=m";
+ case 2941 : return "+proj=tmerc +lat_0=0.1333333333333333 +lon_0=56.76666666666667 +k=1 +x_0=4300000 +y_0=0 +ellps=krass +units=m";
+ case 2942 : return "+proj=utm +zone=28 +ellps=intl +towgs84=-499,-249,314,0,0,0,0 +units=m";
+ case 2943 : return "+proj=utm +zone=28 +ellps=intl +units=m";
+ case 2944 : return "+proj=tmerc +lat_0=0 +lon_0=-55.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2945 : return "+proj=tmerc +lat_0=0 +lon_0=-58.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2946 : return "+proj=tmerc +lat_0=0 +lon_0=-61.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2947 : return "+proj=tmerc +lat_0=0 +lon_0=-64.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2948 : return "+proj=tmerc +lat_0=0 +lon_0=-67.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2949 : return "+proj=tmerc +lat_0=0 +lon_0=-70.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2950 : return "+proj=tmerc +lat_0=0 +lon_0=-73.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2951 : return "+proj=tmerc +lat_0=0 +lon_0=-76.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2952 : return "+proj=tmerc +lat_0=0 +lon_0=-79.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +units=m";
+ case 2953 : return "+proj=sterea +lat_0=46.5 +lon_0=-66.5 +k=0.999912 +x_0=2500000 +y_0=7500000 +ellps=GRS80 +units=m";
+ case 2954 : return "+proj=sterea +lat_0=47.25 +lon_0=-63 +k=0.999912 +x_0=400000 +y_0=800000 +ellps=GRS80 +units=m";
+ case 2955 : return "+proj=utm +zone=11 +ellps=GRS80 +units=m";
+ case 2956 : return "+proj=utm +zone=12 +ellps=GRS80 +units=m";
+ case 2957 : return "+proj=utm +zone=13 +ellps=GRS80 +units=m";
+ case 2958 : return "+proj=utm +zone=17 +ellps=GRS80 +units=m";
+ case 2959 : return "+proj=utm +zone=18 +ellps=GRS80 +units=m";
+ case 2960 : return "+proj=utm +zone=19 +ellps=GRS80 +units=m";
+ case 2961 : return "+proj=utm +zone=20 +ellps=GRS80 +units=m";
+ case 2962 : return "+proj=utm +zone=21 +ellps=GRS80 +units=m";
+ case 2964 : return "+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 2965 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=99999.99989839978 +y_0=249999.9998983998 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2966 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=900000 +y_0=249999.9998983998 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 2967 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=99999.99989839978 +y_0=249999.9998983998 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2968 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=900000 +y_0=249999.9998983998 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 2969 : return "+proj=utm +zone=20 +ellps=intl +towgs84=137,248,-430,0,0,0,0 +units=m";
+ case 2970 : return "+proj=utm +zone=20 +ellps=intl +units=m";
+ case 2971 : return "+proj=utm +zone=22 +ellps=intl +towgs84=-186,230,110,0,0,0,0 +units=m";
+ case 2972 : return "+proj=utm +zone=22 +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0 +units=m";
+ case 2973 : return "+proj=utm +zone=20 +ellps=intl +units=m";
+ case 2975 : return "+proj=utm +zone=40 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2976 : return "+proj=utm +zone=6 +south +ellps=intl +towgs84=162,117,154,0,0,0,0 +units=m";
+ case 2977 : return "+proj=utm +zone=5 +south +ellps=intl +units=m";
+ case 2978 : return "+proj=utm +zone=7 +south +ellps=intl +units=m";
+ case 2979 : return "+proj=utm +zone=42 +south +ellps=intl +towgs84=145,-187,103,0,0,0,0 +units=m";
+ case 2980 : return "+proj=utm +zone=38 +south +ellps=intl +towgs84=-382,-59,-262,0,0,0,0 +units=m";
+ case 2981 : return "+proj=utm +zone=58 +south +ellps=intl +units=m";
+ case 2982 : return "+proj=utm +zone=58 +south +ellps=intl +units=m";
+ case 2983 : return "+proj=utm +zone=58 +south +ellps=intl +towgs84=-122.383,-188.696,103.344,3.5107,-4.9668,-5.7047,4.4798 +units=m";
+ case 2984 : return "+proj=lcc +lat_1=-20.66666666666667 +lat_2=-22.33333333333333 +lat_0=-21.5 +lon_0=166 +x_0=400000 +y_0=300000 +ellps=intl +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2987 : return "+proj=utm +zone=21 +ellps=clrk66 +towgs84=30,430,368,0,0,0,0 +units=m";
+ case 2988 : return "+proj=utm +zone=1 +south +ellps=intl +units=m";
+ case 2989 : return "+proj=utm +zone=20 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 2990 : return "+proj=tmerc +lat_0=-21.11666666666667 +lon_0=55.53333333333333 +k=1 +x_0=50000 +y_0=160000 +ellps=intl +units=m";
+ case 2991 : return "+proj=lcc +lat_1=43 +lat_2=45.5 +lat_0=41.75 +lon_0=-120.5 +x_0=400000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 2992 : return "+proj=lcc +lat_1=43 +lat_2=45.5 +lat_0=41.75 +lon_0=-120.5 +x_0=399999.9999984 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048";
+ case 2993 : return "+proj=lcc +lat_1=43 +lat_2=45.5 +lat_0=41.75 +lon_0=-120.5 +x_0=400000 +y_0=0 +ellps=GRS80 +units=m";
+ case 2994 : return "+proj=lcc +lat_1=43 +lat_2=45.5 +lat_0=41.75 +lon_0=-120.5 +x_0=399999.9999984 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 2995 : return "+proj=utm +zone=58 +south +ellps=intl +units=m";
+ case 2996 : return "+proj=utm +zone=58 +south +ellps=intl +units=m";
+ case 2997 : return "+proj=utm +zone=58 +south +ellps=intl +towgs84=-480.26,-438.32,-643.429,16.3119,20.1721,-4.0349,-111.7 +units=m";
+ case 2998 : return "+proj=utm +zone=58 +south +ellps=intl +units=m";
+ case 2999 : return "+proj=utm +zone=38 +south +ellps=intl +units=m";
+ case 3000 : return "+proj=merc +lon_0=110 +k=0.997 +x_0=3900000 +y_0=900000 +ellps=bessel +units=m";
+ case 3001 : return "+proj=merc +lon_0=110 +k=0.997 +x_0=3900000 +y_0=900000 +ellps=bessel +units=m";
+ case 3002 : return "+proj=merc +lon_0=110 +k=0.997 +x_0=3900000 +y_0=900000 +ellps=bessel +towgs84=-587.8,519.75,145.76,0,0,0,0 +units=m";
+ case 3003 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=0.9996 +x_0=1500000 +y_0=0 +ellps=intl +units=m";
+ case 3004 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=0.9996 +x_0=2520000 +y_0=0 +ellps=intl +units=m";
+ case 3005 : return "+proj=aea +lat_1=50 +lat_2=58.5 +lat_0=45 +lon_0=-126 +x_0=1000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3006 : return "+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3007 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3008 : return "+proj=tmerc +lat_0=0 +lon_0=13.5 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3009 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3010 : return "+proj=tmerc +lat_0=0 +lon_0=16.5 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3011 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3012 : return "+proj=tmerc +lat_0=0 +lon_0=14.25 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3013 : return "+proj=tmerc +lat_0=0 +lon_0=15.75 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3014 : return "+proj=tmerc +lat_0=0 +lon_0=17.25 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3015 : return "+proj=tmerc +lat_0=0 +lon_0=18.75 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3016 : return "+proj=tmerc +lat_0=0 +lon_0=20.25 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3017 : return "+proj=tmerc +lat_0=0 +lon_0=21.75 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3018 : return "+proj=tmerc +lat_0=0 +lon_0=23.25 +k=1 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3019 : return "+proj=tmerc +lat_0=0 +lon_0=11.30827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3020 : return "+proj=tmerc +lat_0=0 +lon_0=13.55827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3021 : return "+proj=tmerc +lat_0=0 +lon_0=15.80827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3022 : return "+proj=tmerc +lat_0=0 +lon_0=18.05827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3023 : return "+proj=tmerc +lat_0=0 +lon_0=20.30827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3024 : return "+proj=tmerc +lat_0=0 +lon_0=22.55827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3025 : return "+proj=tmerc +lat_0=0 +lon_0=11.30827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3026 : return "+proj=tmerc +lat_0=0 +lon_0=13.55827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3027 : return "+proj=tmerc +lat_0=0 +lon_0=15.80827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3028 : return "+proj=tmerc +lat_0=0 +lon_0=18.05827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3029 : return "+proj=tmerc +lat_0=0 +lon_0=20.30827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3030 : return "+proj=tmerc +lat_0=0 +lon_0=22.55827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 3031 : return "+proj=stere +lat_0=-90 +lat_ts=-71 +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3032 : return "+proj=stere +lat_0=-90 +lat_ts=-71 +lon_0=70 +k=1 +x_0=6000000 +y_0=6000000 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3033 : return "+proj=lcc +lat_1=-68.5 +lat_2=-74.5 +lat_0=-50 +lon_0=70 +x_0=6000000 +y_0=6000000 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3034 : return "+proj=lcc +lat_1=35 +lat_2=65 +lat_0=52 +lon_0=10 +x_0=4000000 +y_0=2800000 +ellps=GRS80 +units=m";
+ case 3035 : return "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m";
+ case 3036 : return "+proj=utm +zone=36 +south +ellps=WGS84 +towgs84=0,0,0,-0,-0,-0,0 +units=m";
+ case 3037 : return "+proj=utm +zone=37 +south +ellps=WGS84 +towgs84=0,0,0,-0,-0,-0,0 +units=m";
+ case 3038 : return "+proj=utm +zone=26 +ellps=GRS80 +units=m";
+ case 3039 : return "+proj=utm +zone=27 +ellps=GRS80 +units=m";
+ case 3040 : return "+proj=utm +zone=28 +ellps=GRS80 +units=m";
+ case 3041 : return "+proj=utm +zone=29 +ellps=GRS80 +units=m";
+ case 3042 : return "+proj=utm +zone=30 +ellps=GRS80 +units=m";
+ case 3043 : return "+proj=utm +zone=31 +ellps=GRS80 +units=m";
+ case 3044 : return "+proj=utm +zone=32 +ellps=GRS80 +units=m";
+ case 3045 : return "+proj=utm +zone=33 +ellps=GRS80 +units=m";
+ case 3046 : return "+proj=utm +zone=34 +ellps=GRS80 +units=m";
+ case 3047 : return "+proj=utm +zone=35 +ellps=GRS80 +units=m";
+ case 3048 : return "+proj=utm +zone=36 +ellps=GRS80 +units=m";
+ case 3049 : return "+proj=utm +zone=37 +ellps=GRS80 +units=m";
+ case 3050 : return "+proj=utm +zone=38 +ellps=GRS80 +units=m";
+ case 3051 : return "+proj=utm +zone=39 +ellps=GRS80 +units=m";
+ case 3054 : return "+proj=utm +zone=26 +ellps=intl +towgs84=-73,46,-86,0,0,0,0 +units=m";
+ case 3055 : return "+proj=utm +zone=27 +ellps=intl +towgs84=-73,46,-86,0,0,0,0 +units=m";
+ case 3056 : return "+proj=utm +zone=28 +ellps=intl +towgs84=-73,46,-86,0,0,0,0 +units=m";
+ case 3057 : return "+proj=lcc +lat_1=64.25 +lat_2=65.75 +lat_0=65 +lon_0=-19 +x_0=500000 +y_0=500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3058 : return "+proj=tmerc +lat_0=0 +lon_0=-8.5 +k=1 +x_0=50000 +y_0=-7800000 +ellps=intl +towgs84=982.609,552.753,-540.873,32.3934,-153.257,-96.2266,16.805 +units=m";
+ case 3059 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9996 +x_0=500000 +y_0=-6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3060 : return "+proj=utm +zone=58 +south +ellps=intl +units=m";
+ case 3061 : return "+proj=utm +zone=28 +ellps=intl +units=m";
+ case 3062 : return "+proj=utm +zone=26 +ellps=intl +units=m";
+ case 3063 : return "+proj=utm +zone=26 +ellps=intl +units=m";
+ case 3064 : return "+proj=utm +zone=32 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3065 : return "+proj=utm +zone=33 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3066 : return "+proj=tmerc +lat_0=0 +lon_0=37 +k=0.9998 +x_0=500000 +y_0=-3000000 +ellps=intl +units=m";
+ case 3067 : return "+proj=utm +zone=35 +ellps=GRS80 +units=m";
+ case 3068 : return "+proj=cass +lat_0=52.41864827777778 +lon_0=13.62720366666667 +x_0=40000 +y_0=10000 +ellps=bessel +datum=potsdam +units=m";
+ case 3069 : return "+proj=tmerc +lat_0=0 +lon_0=-90 +k=0.9996 +x_0=500000 +y_0=-4500000 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 3070 : return "+proj=tmerc +lat_0=0 +lon_0=-90 +k=0.9996 +x_0=520000 +y_0=-4480000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3071 : return "+proj=tmerc +lat_0=0 +lon_0=-90 +k=0.9996 +x_0=520000 +y_0=-4480000 +ellps=GRS80 +units=m";
+ case 3072 : return "+proj=tmerc +lat_0=43.83333333333334 +lon_0=-67.875 +k=0.99998 +x_0=700000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3073 : return "+proj=tmerc +lat_0=43 +lon_0=-69.125 +k=0.99998 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3074 : return "+proj=tmerc +lat_0=42.83333333333334 +lon_0=-70.375 +k=0.99998 +x_0=300000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3075 : return "+proj=tmerc +lat_0=43.83333333333334 +lon_0=-67.875 +k=0.99998 +x_0=700000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3076 : return "+proj=tmerc +lat_0=43 +lon_0=-69.125 +k=0.99998 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3077 : return "+proj=tmerc +lat_0=42.83333333333334 +lon_0=-70.375 +k=0.99998 +x_0=300000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3078 : return "+proj=omerc +lat_0=45.30916666666666 +lonc=-86 +alpha=337.25556 +k=0.9996 +x_0=2546731.496 +y_0=-4354009.816 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3079 : return "+proj=omerc +lat_0=45.30916666666666 +lonc=-86 +alpha=337.25556 +k=0.9996 +x_0=2546731.496 +y_0=-4354009.816 +ellps=GRS80 +units=m";
+ case 3080 : return "+proj=lcc +lat_1=27.41666666666667 +lat_2=34.91666666666666 +lat_0=31.16666666666667 +lon_0=-100 +x_0=914400 +y_0=914400 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048";
+ case 3081 : return "+proj=lcc +lat_1=27.41666666666667 +lat_2=34.91666666666666 +lat_0=31.16666666666667 +lon_0=-100 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3082 : return "+proj=lcc +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=5000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3083 : return "+proj=aea +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=6000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3084 : return "+proj=lcc +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=5000000 +ellps=GRS80 +units=m";
+ case 3085 : return "+proj=aea +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=6000000 +ellps=GRS80 +units=m";
+ case 3086 : return "+proj=aea +lat_1=24 +lat_2=31.5 +lat_0=24 +lon_0=-84 +x_0=400000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3087 : return "+proj=aea +lat_1=24 +lat_2=31.5 +lat_0=24 +lon_0=-84 +x_0=400000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3088 : return "+proj=lcc +lat_1=37.08333333333334 +lat_2=38.66666666666666 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=1500000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3089 : return "+proj=lcc +lat_1=37.08333333333334 +lat_2=38.66666666666666 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=1500000 +y_0=999999.9998983998 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3090 : return "+proj=lcc +lat_1=37.08333333333334 +lat_2=38.66666666666666 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=1500000 +y_0=1000000 +ellps=GRS80 +units=m";
+ case 3091 : return "+proj=lcc +lat_1=37.08333333333334 +lat_2=38.66666666666666 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=1500000 +y_0=999999.9998983998 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3092 : return "+proj=utm +zone=51 +ellps=bessel +units=m";
+ case 3093 : return "+proj=utm +zone=52 +ellps=bessel +units=m";
+ case 3094 : return "+proj=utm +zone=53 +ellps=bessel +units=m";
+ case 3095 : return "+proj=utm +zone=54 +ellps=bessel +units=m";
+ case 3096 : return "+proj=utm +zone=55 +ellps=bessel +units=m";
+ case 3097 : return "+proj=utm +zone=51 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3098 : return "+proj=utm +zone=52 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3099 : return "+proj=utm +zone=53 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3100 : return "+proj=utm +zone=54 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3101 : return "+proj=utm +zone=55 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3102 : return "+proj=lcc +lat_1=-14.26666666666667 +lat_0=-14.26666666666667 +lon_0=-170 +k_0=1 +x_0=152400.3048006096 +y_0=95169.31165862332 +ellps=clrk66 +towgs84=-115,118,426,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3103 : return "+proj=utm +zone=28 +ellps=clrk80 +units=m";
+ case 3104 : return "+proj=utm +zone=29 +ellps=clrk80 +units=m";
+ case 3105 : return "+proj=utm +zone=30 +ellps=clrk80 +units=m";
+ case 3106 : return "+proj=tmerc +lat_0=0 +lon_0=90 +k=0.9996 +x_0=500000 +y_0=0 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 3107 : return "+proj=lcc +lat_1=-28 +lat_2=-36 +lat_0=-32 +lon_0=135 +x_0=1000000 +y_0=2000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3108 : return "+proj=tmerc +lat_0=49.5 +lon_0=-2.416666666666667 +k=0.999997 +x_0=47000 +y_0=50000 +ellps=GRS80 +units=m";
+ case 3109 : return "+proj=tmerc +lat_0=49.225 +lon_0=-2.135 +k=0.9999999000000001 +x_0=40000 +y_0=70000 +ellps=GRS80 +units=m";
+ case 3110 : return "+proj=lcc +lat_1=-36 +lat_2=-38 +lat_0=-37 +lon_0=145 +x_0=2500000 +y_0=4500000 +ellps=aust_SA +units=m";
+ case 3111 : return "+proj=lcc +lat_1=-36 +lat_2=-38 +lat_0=-37 +lon_0=145 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3112 : return "+proj=lcc +lat_1=-18 +lat_2=-36 +lat_0=0 +lon_0=134 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3113 : return "+proj=tmerc +lat_0=-28 +lon_0=153 +k=0.99999 +x_0=50000 +y_0=100000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3114 : return "+proj=tmerc +lat_0=4.596200416666666 +lon_0=-80.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3115 : return "+proj=tmerc +lat_0=4.596200416666666 +lon_0=-77.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3116 : return "+proj=tmerc +lat_0=4.596200416666666 +lon_0=-74.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3117 : return "+proj=tmerc +lat_0=4.596200416666666 +lon_0=-71.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3118 : return "+proj=tmerc +lat_0=4.596200416666666 +lon_0=-68.07750791666666 +k=1 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3119 : return "+proj=tmerc +lat_0=0 +lon_0=10.5 +k=0.999 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=-206.1,-174.7,-87.7,0,0,0,0 +units=m";
+ case 3120 : return "+proj=sterea +lat_0=50.625 +lon_0=21.08333333333333 +k=0.9998 +x_0=4637000 +y_0=5467000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3121 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +towgs84=-127.62,-67.24,-47.04,-3.068,4.903,1.578,-1.06 +units=m";
+ case 3122 : return "+proj=tmerc +lat_0=0 +lon_0=119 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +towgs84=-127.62,-67.24,-47.04,-3.068,4.903,1.578,-1.06 +units=m";
+ case 3123 : return "+proj=tmerc +lat_0=0 +lon_0=121 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +towgs84=-127.62,-67.24,-47.04,-3.068,4.903,1.578,-1.06 +units=m";
+ case 3124 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +towgs84=-127.62,-67.24,-47.04,-3.068,4.903,1.578,-1.06 +units=m";
+ case 3125 : return "+proj=tmerc +lat_0=0 +lon_0=125 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +towgs84=-127.62,-67.24,-47.04,-3.068,4.903,1.578,-1.06 +units=m";
+ case 3126 : return "+proj=tmerc +lat_0=0 +lon_0=19 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3127 : return "+proj=tmerc +lat_0=0 +lon_0=20 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3128 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3129 : return "+proj=tmerc +lat_0=0 +lon_0=22 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3130 : return "+proj=tmerc +lat_0=0 +lon_0=23 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3131 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3132 : return "+proj=tmerc +lat_0=0 +lon_0=25 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3133 : return "+proj=tmerc +lat_0=0 +lon_0=26 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3134 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3135 : return "+proj=tmerc +lat_0=0 +lon_0=28 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3136 : return "+proj=tmerc +lat_0=0 +lon_0=29 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3137 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3138 : return "+proj=tmerc +lat_0=0 +lon_0=31 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3140 : return "+proj=cass +lat_0=-18 +lon_0=178 +x_0=109435.392 +y_0=141622.272 +a=6378306.3696 +b=6356571.996 +towgs84=51,391,-36,0,0,0,0 +to_meter=0.201168";
+ case 3141 : return "+proj=utm +zone=60 +south +ellps=intl +towgs84=265.025,384.929,-194.046,0,0,0,0 +units=m";
+ case 3142 : return "+proj=utm +zone=1 +south +ellps=intl +towgs84=265.025,384.929,-194.046,0,0,0,0 +units=m";
+ case 3143 : return "+proj=tmerc +lat_0=-17 +lon_0=178.75 +k=0.99985 +x_0=2000000 +y_0=4000000 +ellps=WGS72 +units=m";
+ case 3146 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=1 +x_0=6500000 +y_0=0 +ellps=krass +units=m";
+ case 3147 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 3148 : return "+proj=utm +zone=48 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 3149 : return "+proj=utm +zone=49 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 3150 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=1 +x_0=6500000 +y_0=0 +ellps=krass +units=m";
+ case 3151 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 3152 : return "+proj=tmerc +lat_0=0 +lon_0=18.05779 +k=0.99999425 +x_0=100178.1808 +y_0=-6500614.7836 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3153 : return "+proj=aea +lat_1=50 +lat_2=58.5 +lat_0=45 +lon_0=-126 +x_0=1000000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3154 : return "+proj=utm +zone=7 +ellps=GRS80 +units=m";
+ case 3155 : return "+proj=utm +zone=8 +ellps=GRS80 +units=m";
+ case 3156 : return "+proj=utm +zone=9 +ellps=GRS80 +units=m";
+ case 3157 : return "+proj=utm +zone=10 +ellps=GRS80 +units=m";
+ case 3158 : return "+proj=utm +zone=14 +ellps=GRS80 +units=m";
+ case 3159 : return "+proj=utm +zone=15 +ellps=GRS80 +units=m";
+ case 3160 : return "+proj=utm +zone=16 +ellps=GRS80 +units=m";
+ case 3161 : return "+proj=lcc +lat_1=44.5 +lat_2=53.5 +lat_0=0 +lon_0=-85 +x_0=930000 +y_0=6430000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3162 : return "+proj=lcc +lat_1=44.5 +lat_2=53.5 +lat_0=0 +lon_0=-85 +x_0=930000 +y_0=6430000 +ellps=GRS80 +units=m";
+ case 3163 : return "+proj=lcc +lat_1=-20.66666666666667 +lat_2=-22.33333333333333 +lat_0=-21.5 +lon_0=166 +x_0=400000 +y_0=300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3164 : return "+proj=utm +zone=58 +south +ellps=WGS84 +towgs84=-56.263,16.136,-22.856,0,0,0,0 +units=m";
+ case 3165 : return "+proj=lcc +lat_1=-22.24469175 +lat_2=-22.29469175 +lat_0=-22.26969175 +lon_0=166.44242575 +x_0=0.66 +y_0=1.02 +ellps=intl +units=m";
+ case 3166 : return "+proj=lcc +lat_1=-22.24472222222222 +lat_2=-22.29472222222222 +lat_0=-22.26972222222222 +lon_0=166.4425 +x_0=8.313000000000001 +y_0=-2.354 +ellps=intl +units=m";
+ case 3167 : return "+proj=omerc +lat_0=4 +lonc=102.25 +alpha=323.0257905 +k=0.99984 +x_0=40000 +y_0=0 +a=6377295.664 +b=6356094.667915204 +to_meter=20.116756";
+ case 3168 : return "+proj=omerc +lat_0=4 +lonc=102.25 +alpha=323.0257905 +k=0.99984 +x_0=804670.24 +y_0=0 +a=6377295.664 +b=6356094.667915204 +units=m";
+ case 3169 : return "+proj=utm +zone=57 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3170 : return "+proj=utm +zone=58 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3171 : return "+proj=utm +zone=59 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3172 : return "+proj=utm +zone=59 +south +ellps=intl +units=m";
+ case 3174 : return "+proj=aea +lat_1=42.122774 +lat_2=49.01518 +lat_0=45.568977 +lon_0=-84.455955 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3175 : return "+proj=aea +lat_1=42.122774 +lat_2=49.01518 +lat_0=45.568977 +lon_0=-83.248627 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3176 : return "+proj=tmerc +lat_0=0 +lon_0=106 +k=0.9996 +x_0=500000 +y_0=0 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 3177 : return "+proj=tmerc +lat_0=0 +lon_0=17 +k=0.9965000000000001 +x_0=1000000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3178 : return "+proj=utm +zone=18 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3179 : return "+proj=utm +zone=19 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3180 : return "+proj=utm +zone=20 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3181 : return "+proj=utm +zone=21 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3182 : return "+proj=utm +zone=22 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3183 : return "+proj=utm +zone=23 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3184 : return "+proj=utm +zone=24 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3185 : return "+proj=utm +zone=25 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3186 : return "+proj=utm +zone=26 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3187 : return "+proj=utm +zone=27 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3188 : return "+proj=utm +zone=28 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3189 : return "+proj=utm +zone=29 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3190 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3191 : return "+proj=tmerc +lat_0=0 +lon_0=11 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3192 : return "+proj=tmerc +lat_0=0 +lon_0=13 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3193 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3194 : return "+proj=tmerc +lat_0=0 +lon_0=17 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3195 : return "+proj=tmerc +lat_0=0 +lon_0=19 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3196 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3197 : return "+proj=tmerc +lat_0=0 +lon_0=23 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3198 : return "+proj=tmerc +lat_0=0 +lon_0=25 +k=0.99995 +x_0=200000 +y_0=0 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3199 : return "+proj=utm +zone=32 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3200 : return "+proj=lcc +lat_1=32.5 +lat_0=32.5 +lon_0=45 +k_0=0.9987864078000001 +x_0=1500000 +y_0=1166200 +ellps=clrk80 +units=m";
+ case 3201 : return "+proj=utm +zone=33 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3202 : return "+proj=utm +zone=34 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3203 : return "+proj=utm +zone=35 +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0 +units=m";
+ case 3204 : return "+proj=lcc +lat_1=-60.66666666666666 +lat_2=-63.33333333333334 +lat_0=-90 +lon_0=-66 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3205 : return "+proj=lcc +lat_1=-60.66666666666666 +lat_2=-63.33333333333334 +lat_0=-90 +lon_0=-54 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3206 : return "+proj=lcc +lat_1=-60.66666666666666 +lat_2=-63.33333333333334 +lat_0=-90 +lon_0=-42 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3207 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=-174 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3208 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=-66 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3209 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=-54 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3210 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=42 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3211 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=54 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3212 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=66 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3213 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=78 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3214 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=90 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3215 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=102 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3216 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=114 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3217 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=126 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3218 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=138 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3219 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=150 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3220 : return "+proj=lcc +lat_1=-64.66666666666667 +lat_2=-67.33333333333333 +lat_0=-90 +lon_0=162 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3221 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=-102 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3222 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=-90 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3223 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=-78 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3224 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=-66 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3225 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=-18 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3226 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=-6 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3227 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=6 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3228 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=18 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3229 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=30 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3230 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=42 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3231 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=54 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3232 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=66 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3233 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=78 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3234 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=90 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3235 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=102 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3236 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=114 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3237 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=126 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3238 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=138 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3239 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=150 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3240 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=162 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3241 : return "+proj=lcc +lat_1=-68.66666666666667 +lat_2=-71.33333333333333 +lat_0=-90 +lon_0=174 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3242 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=-153 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3243 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=-135 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3244 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=-117 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3245 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=-99 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3246 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=-81 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3247 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=-63 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3248 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=-27 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3249 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=-9 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3250 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=9 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3251 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=27 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3252 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=45 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3253 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=63 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3254 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=81 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3255 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=99 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3256 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=117 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3257 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=135 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3258 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=153 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3259 : return "+proj=lcc +lat_1=-72.66666666666667 +lat_2=-75.33333333333333 +lat_0=-90 +lon_0=171 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3260 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=-168 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3261 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=-144 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3262 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=-120 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3263 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=-96 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3264 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=-72 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3265 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=-48 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3266 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=-24 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3267 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3268 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=24 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3269 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=48 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3270 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=72 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3271 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=96 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3272 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=120 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3273 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=144 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3274 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-90 +lon_0=168 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3275 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-165 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3276 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-135 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3277 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-105 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3278 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-75 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3279 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3280 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-15 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3281 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=15 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3282 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=45 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3283 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=75 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3284 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=105 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3285 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=135 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3286 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=165 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3287 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-150 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3288 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-90 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3289 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=-30 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3290 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=30 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3291 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=90 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3292 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=150 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3293 : return "+proj=stere +lat_0=-90 +lat_ts=-80.23861111111111 +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3294 : return "+proj=lcc +lat_1=-76.66666666666667 +lat_2=-79.33333333333333 +lat_0=-78 +lon_0=162 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3296 : return "+proj=utm +zone=5 +south +ellps=GRS80 +units=m";
+ case 3297 : return "+proj=utm +zone=6 +south +ellps=GRS80 +units=m";
+ case 3298 : return "+proj=utm +zone=7 +south +ellps=GRS80 +units=m";
+ case 3299 : return "+proj=utm +zone=8 +south +ellps=GRS80 +units=m";
+ case 3300 : return "+proj=lcc +lat_1=59.33333333333334 +lat_2=58 +lat_0=57.51755393055556 +lon_0=24 +x_0=500000 +y_0=6375000 +ellps=GRS80 +towgs84=0.055,-0.541,-0.185,0.0183,-0.0003,-0.007,-0.014 +units=m";
+ case 3301 : return "+proj=lcc +lat_1=59.33333333333334 +lat_2=58 +lat_0=57.51755393055556 +lon_0=24 +x_0=500000 +y_0=6375000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3302 : return "+proj=utm +zone=7 +south +ellps=intl +units=m";
+ case 3303 : return "+proj=utm +zone=7 +south +ellps=intl +towgs84=347.103,1078.12,2623.92,-33.8875,70.6773,-9.3943,186.074 +units=m";
+ case 3304 : return "+proj=utm +zone=6 +south +ellps=intl +units=m";
+ case 3305 : return "+proj=utm +zone=6 +south +ellps=intl +towgs84=215.525,149.593,176.229,-3.2624,-1.692,-1.1571,10.4773 +units=m";
+ case 3306 : return "+proj=utm +zone=5 +south +ellps=intl +towgs84=217.037,86.959,23.956,0,0,0,0 +units=m";
+ case 3307 : return "+proj=utm +zone=39 +ellps=WGS84 +towgs84=0,-0.15,0.68,0,0,0,0 +units=m";
+ case 3308 : return "+proj=lcc +lat_1=-30.75 +lat_2=-35.75 +lat_0=-33.25 +lon_0=147 +x_0=9300000 +y_0=4500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3309 : return "+proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 3310 : return "+proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3311 : return "+proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=GRS80 +units=m";
+ case 3312 : return "+proj=utm +zone=21 +ellps=intl +towgs84=-186,230,110,0,0,0,0 +units=m";
+ case 3313 : return "+proj=utm +zone=21 +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0 +units=m";
+ case 3314 : return "+proj=lcc +lat_1=-6.5 +lat_2=-11.5 +lat_0=0 +lon_0=26 +x_0=0 +y_0=0 +ellps=clrk66 +units=m";
+ case 3315 : return "+proj=tmerc +lat_0=-9 +lon_0=26 +k=0.9998 +x_0=0 +y_0=0 +ellps=clrk66 +units=m";
+ case 3316 : return "+proj=tmerc +lat_0=0 +lon_0=22 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3317 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3318 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3319 : return "+proj=tmerc +lat_0=0 +lon_0=14 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3320 : return "+proj=tmerc +lat_0=0 +lon_0=16 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3321 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3322 : return "+proj=tmerc +lat_0=0 +lon_0=20 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3323 : return "+proj=tmerc +lat_0=0 +lon_0=22 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3324 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3325 : return "+proj=tmerc +lat_0=0 +lon_0=26 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3326 : return "+proj=tmerc +lat_0=0 +lon_0=28 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3327 : return "+proj=tmerc +lat_0=0 +lon_0=30 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 3328 : return "+proj=sterea +lat_0=52.16666666666666 +lon_0=19.16666666666667 +k=0.999714 +x_0=500000 +y_0=500000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3329 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=5500000 +y_0=0 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3330 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=1 +x_0=6500000 +y_0=0 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3331 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=7500000 +y_0=0 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3332 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=1 +x_0=8500000 +y_0=0 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3333 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=3500000 +y_0=0 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3334 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=4500000 +y_0=0 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3335 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=5500000 +y_0=0 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ case 3336 : return "+proj=utm +zone=42 +south +ellps=intl +towgs84=145,-187,103,0,0,0,0 +units=m";
+ case 3337 : return "+proj=lcc +lat_1=-20.19506944444445 +lat_0=-20.19506944444445 +lon_0=57.52182777777778 +k_0=1 +x_0=1000000 +y_0=1000000 +ellps=clrk80 +towgs84=-770.1,158.4,-498.2,0,0,0,0 +units=m";
+ case 3338 : return "+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3339 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +towgs84=-79.9,-158,-168.9,0,0,0,0 +units=m";
+ case 3340 : return "+proj=tmerc +lat_0=0 +lon_0=14 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +towgs84=-79.9,-158,-168.9,0,0,0,0 +units=m";
+ case 3341 : return "+proj=tmerc +lat_0=0 +lon_0=16 +k=0.9999 +x_0=500000 +y_0=10000000 +ellps=clrk80 +towgs84=-79.9,-158,-168.9,0,0,0,0 +units=m";
+ case 3342 : return "+proj=utm +zone=33 +south +ellps=clrk80 +towgs84=-79.9,-158,-168.9,0,0,0,0 +units=m";
+ case 3343 : return "+proj=utm +zone=28 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3344 : return "+proj=utm +zone=29 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3345 : return "+proj=utm +zone=30 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3346 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9998 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3347 : return "+proj=lcc +lat_1=49 +lat_2=77 +lat_0=63.390675 +lon_0=-91.86666666666666 +x_0=6200000 +y_0=3000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3348 : return "+proj=lcc +lat_1=49 +lat_2=77 +lat_0=63.390675 +lon_0=-91.86666666666666 +x_0=6200000 +y_0=3000000 +ellps=GRS80 +units=m";
+ case 3349 : return "+proj=merc +lon_0=-150 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3350 : return "+proj=tmerc +lat_0=0.1 +lon_0=21.95 +k=1 +x_0=250000 +y_0=0 +ellps=krass +units=m";
+ case 3351 : return "+proj=tmerc +lat_0=0.1 +lon_0=24.95 +k=1 +x_0=1250000 +y_0=0 +ellps=krass +units=m";
+ case 3352 : return "+proj=tmerc +lat_0=0.1 +lon_0=27.95 +k=1 +x_0=2250000 +y_0=0 +ellps=krass +units=m";
+ case 3353 : return "+proj=utm +zone=32 +south +ellps=intl +units=m";
+ case 3354 : return "+proj=utm +zone=32 +south +ellps=intl +units=m";
+ case 3355 : return "+proj=tmerc +lat_0=30 +lon_0=31 +k=1 +x_0=615000 +y_0=810000 +ellps=helmert +towgs84=-146.21,112.63,4.05,0,0,0,0 +units=m";
+ case 3356 : return "+proj=utm +zone=17 +ellps=clrk66 +towgs84=67.8,106.1,138.8,0,0,0,0 +units=m";
+ case 3357 : return "+proj=utm +zone=17 +ellps=clrk66 +units=m";
+ case 3358 : return "+proj=lcc +lat_1=36.16666666666666 +lat_2=34.33333333333334 +lat_0=33.75 +lon_0=-79 +x_0=609601.22 +y_0=0 +ellps=GRS80 +units=m";
+ case 3359 : return "+proj=lcc +lat_1=36.16666666666666 +lat_2=34.33333333333334 +lat_0=33.75 +lon_0=-79 +x_0=609601.2192024385 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 3360 : return "+proj=lcc +lat_1=34.83333333333334 +lat_2=32.5 +lat_0=31.83333333333333 +lon_0=-81 +x_0=609600 +y_0=0 +ellps=GRS80 +units=m";
+ case 3361 : return "+proj=lcc +lat_1=34.83333333333334 +lat_2=32.5 +lat_0=31.83333333333333 +lon_0=-81 +x_0=609600 +y_0=0 +ellps=GRS80 +to_meter=0.3048";
+ case 3362 : return "+proj=lcc +lat_1=41.95 +lat_2=40.88333333333333 +lat_0=40.16666666666666 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3363 : return "+proj=lcc +lat_1=41.95 +lat_2=40.88333333333333 +lat_0=40.16666666666666 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3364 : return "+proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3365 : return "+proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3366 : return "+proj=cass +lat_0=22.31213333333334 +lon_0=114.1785555555556 +x_0=40243.57775604237 +y_0=19069.93351512578 +a=6378293.645208759 +b=6356617.987679838 +units=m";
+ case 3367 : return "+proj=utm +zone=28 +ellps=clrk80 +units=m";
+ case 3368 : return "+proj=utm +zone=29 +ellps=clrk80 +units=m";
+ case 3369 : return "+proj=utm +zone=30 +ellps=clrk80 +units=m";
+ case 3370 : return "+proj=utm +zone=59 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 3371 : return "+proj=utm +zone=60 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 3372 : return "+proj=utm +zone=59 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3373 : return "+proj=utm +zone=60 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3374 : return "+proj=utm +zone=29 +ellps=intl +units=m";
+ case 3375 : return "+proj=omerc +lat_0=4 +lonc=102.25 +alpha=323.0257964666666 +k=0.99984 +x_0=804671 +y_0=0 +ellps=GRS80 +units=m";
+ case 3376 : return "+proj=omerc +lat_0=4 +lonc=115 +alpha=53.31580995 +k=0.99984 +x_0=0 +y_0=0 +ellps=GRS80 +units=m";
+ case 3377 : return "+proj=cass +lat_0=2.121679744444445 +lon_0=103.4279362361111 +x_0=-14810.562 +y_0=8758.32 +ellps=GRS80 +units=m";
+ case 3378 : return "+proj=cass +lat_0=2.682347636111111 +lon_0=101.9749050416667 +x_0=3673.785 +y_0=-4240.573 +ellps=GRS80 +units=m";
+ case 3379 : return "+proj=cass +lat_0=3.769388088888889 +lon_0=102.3682989833333 +x_0=-7368.228 +y_0=6485.858 +ellps=GRS80 +units=m";
+ case 3380 : return "+proj=cass +lat_0=3.68464905 +lon_0=101.3891079138889 +x_0=-34836.161 +y_0=56464.049 +ellps=GRS80 +units=m";
+ case 3381 : return "+proj=cass +lat_0=4.9762852 +lon_0=103.070275625 +x_0=19594.245 +y_0=3371.895 +ellps=GRS80 +units=m";
+ case 3382 : return "+proj=cass +lat_0=5.421517541666667 +lon_0=100.3443769638889 +x_0=-23.414 +y_0=62.283 +ellps=GRS80 +units=m";
+ case 3383 : return "+proj=cass +lat_0=5.964672713888889 +lon_0=100.6363711111111 +x_0=0 +y_0=0 +ellps=GRS80 +units=m";
+ case 3384 : return "+proj=cass +lat_0=4.859063022222222 +lon_0=100.8154105861111 +x_0=-1.769 +y_0=133454.779 +ellps=GRS80 +units=m";
+ case 3385 : return "+proj=cass +lat_0=5.972543658333334 +lon_0=102.2952416694444 +x_0=13227.851 +y_0=8739.894 +ellps=GRS80 +units=m";
+ case 3386 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=1 +x_0=500000 +y_0=0 +ellps=intl +towgs84=-96.0617,-82.4278,-121.743,4.80107,0.34543,-1.37646,1.4964 +units=m";
+ case 3387 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=5500000 +y_0=0 +ellps=intl +towgs84=-96.0617,-82.4278,-121.743,4.80107,0.34543,-1.37646,1.4964 +units=m";
+ case 3388 : return "+proj=merc +lon_0=51 +k=1 +x_0=0 +y_0=0 +ellps=krass +units=m";
+ case 3389 : return "+proj=tmerc +lat_0=0 +lon_0=180 +k=1 +x_0=60500000 +y_0=0 +ellps=krass +units=m";
+ case 3390 : return "+proj=tmerc +lat_0=0 +lon_0=180 +k=1 +x_0=60500000 +y_0=0 +ellps=krass +units=m";
+ case 3391 : return "+proj=utm +zone=37 +ellps=clrk80 +towgs84=84.1,-320.1,218.7,0,0,0,0 +units=m";
+ case 3392 : return "+proj=utm +zone=38 +ellps=clrk80 +towgs84=84.1,-320.1,218.7,0,0,0,0 +units=m";
+ case 3393 : return "+proj=utm +zone=39 +ellps=clrk80 +towgs84=84.1,-320.1,218.7,0,0,0,0 +units=m";
+ case 3394 : return "+proj=lcc +lat_1=32.5 +lat_0=32.5 +lon_0=45 +k_0=0.9987864078000001 +x_0=1500000 +y_0=1166200 +ellps=clrk80 +units=m";
+ case 3395 : return "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3396 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0 +ellps=bessel +units=m";
+ case 3397 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=bessel +units=m";
+ case 3398 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=bessel +units=m";
+ case 3399 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=5500000 +y_0=0 +ellps=bessel +units=m";
+ case 3400 : return "+proj=tmerc +lat_0=0 +lon_0=-115 +k=0.9992 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3401 : return "+proj=tmerc +lat_0=0 +lon_0=-115 +k=0.9992 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3402 : return "+proj=tmerc +lat_0=0 +lon_0=-115 +k=0.9992 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3403 : return "+proj=tmerc +lat_0=0 +lon_0=-115 +k=0.9992 +x_0=0 +y_0=0 +ellps=GRS80 +units=m";
+ case 3404 : return "+proj=lcc +lat_1=36.16666666666666 +lat_2=34.33333333333334 +lat_0=33.75 +lon_0=-79 +x_0=609601.2192024384 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3405 : return "+proj=utm +zone=48 +ellps=WGS84 +units=m";
+ case 3406 : return "+proj=utm +zone=49 +ellps=WGS84 +units=m";
+ case 3407 : return "+proj=cass +lat_0=22.31213333333334 +lon_0=114.1785555555556 +x_0=40243.57775604237 +y_0=19069.93351512578 +a=6378293.645208759 +b=6356617.987679838 +to_meter=0.3047972654";
+ case 3408 : return "+proj=laea +lat_0=90 +lon_0=0 +x_0=0 +y_0=0 +a=6371228 +b=6371228 +units=m";
+ case 3409 : return "+proj=laea +lat_0=-90 +lon_0=0 +x_0=0 +y_0=0 +a=6371228 +b=6371228 +units=m";
+ case 3411 : return "+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m";
+ case 3412 : return "+proj=stere +lat_0=-90 +lat_ts=-70 +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m";
+ case 3413 : return "+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3414 : return "+proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m";
+ case 3415 : return "+proj=lcc +lat_1=18 +lat_2=24 +lat_0=21 +lon_0=114 +x_0=500000 +y_0=500000 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 3416 : return "+proj=lcc +lat_1=49 +lat_2=46 +lat_0=47.5 +lon_0=13.33333333333333 +x_0=400000 +y_0=400000 +ellps=GRS80 +units=m";
+ case 3417 : return "+proj=lcc +lat_1=43.26666666666667 +lat_2=42.06666666666667 +lat_0=41.5 +lon_0=-93.5 +x_0=1500000 +y_0=999999.9999898402 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3418 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.61666666666667 +lat_0=40 +lon_0=-93.5 +x_0=500000.00001016 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3419 : return "+proj=lcc +lat_1=39.78333333333333 +lat_2=38.71666666666667 +lat_0=38.33333333333334 +lon_0=-98 +x_0=399999.99998984 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3420 : return "+proj=lcc +lat_1=38.56666666666667 +lat_2=37.26666666666667 +lat_0=36.66666666666666 +lon_0=-98.5 +x_0=399999.99998984 +y_0=399999.99998984 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3421 : return "+proj=tmerc +lat_0=34.75 +lon_0=-115.5833333333333 +k=0.9999 +x_0=200000.00001016 +y_0=8000000.000010163 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3422 : return "+proj=tmerc +lat_0=34.75 +lon_0=-116.6666666666667 +k=0.9999 +x_0=500000.00001016 +y_0=6000000 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3423 : return "+proj=tmerc +lat_0=34.75 +lon_0=-118.5833333333333 +k=0.9999 +x_0=800000.0000101599 +y_0=3999999.99998984 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3424 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3425 : return "+proj=lcc +lat_1=43.26666666666667 +lat_2=42.06666666666667 +lat_0=41.5 +lon_0=-93.5 +x_0=1500000 +y_0=999999.9999898402 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3426 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.61666666666667 +lat_0=40 +lon_0=-93.5 +x_0=500000.00001016 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3427 : return "+proj=lcc +lat_1=39.78333333333333 +lat_2=38.71666666666667 +lat_0=38.33333333333334 +lon_0=-98 +x_0=399999.99998984 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3428 : return "+proj=lcc +lat_1=38.56666666666667 +lat_2=37.26666666666667 +lat_0=36.66666666666666 +lon_0=-98.5 +x_0=399999.99998984 +y_0=399999.99998984 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3429 : return "+proj=tmerc +lat_0=34.75 +lon_0=-115.5833333333333 +k=0.9999 +x_0=200000.00001016 +y_0=8000000.000010163 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3430 : return "+proj=tmerc +lat_0=34.75 +lon_0=-116.6666666666667 +k=0.9999 +x_0=500000.00001016 +y_0=6000000 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3431 : return "+proj=tmerc +lat_0=34.75 +lon_0=-118.5833333333333 +k=0.9999 +x_0=800000.0000101599 +y_0=3999999.99998984 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3432 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3433 : return "+proj=lcc +lat_1=36.23333333333333 +lat_2=34.93333333333333 +lat_0=34.33333333333334 +lon_0=-92 +x_0=399999.99998984 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3434 : return "+proj=lcc +lat_1=34.76666666666667 +lat_2=33.3 +lat_0=32.66666666666666 +lon_0=-92 +x_0=399999.99998984 +y_0=399999.99998984 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3435 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-88.33333333333333 +k=0.9999749999999999 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3436 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-90.16666666666667 +k=0.999941177 +x_0=699999.9999898402 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3437 : return "+proj=tmerc +lat_0=42.5 +lon_0=-71.66666666666667 +k=0.999966667 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3438 : return "+proj=tmerc +lat_0=41.08333333333334 +lon_0=-71.5 +k=0.99999375 +x_0=99999.99998983997 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3439 : return "+proj=utm +zone=39 +ellps=clrk80 +units=m";
+ case 3440 : return "+proj=utm +zone=40 +ellps=clrk80 +units=m";
+ case 3441 : return "+proj=lcc +lat_1=36.23333333333333 +lat_2=34.93333333333333 +lat_0=34.33333333333334 +lon_0=-92 +x_0=399999.99998984 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3442 : return "+proj=lcc +lat_1=34.76666666666667 +lat_2=33.3 +lat_0=32.66666666666666 +lon_0=-92 +x_0=399999.99998984 +y_0=399999.99998984 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3443 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-88.33333333333333 +k=0.9999749999999999 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3444 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-90.16666666666667 +k=0.999941177 +x_0=699999.9999898402 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3445 : return "+proj=tmerc +lat_0=42.5 +lon_0=-71.66666666666667 +k=0.999966667 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3446 : return "+proj=tmerc +lat_0=41.08333333333334 +lon_0=-71.5 +k=0.99999375 +x_0=99999.99998983997 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3447 : return "+proj=lcc +lat_1=49.83333333333334 +lat_2=51.16666666666666 +lat_0=50.797815 +lon_0=4.359215833333333 +x_0=150328 +y_0=166262 +ellps=GRS80 +units=m";
+ case 3448 : return "+proj=lcc +lat_1=18 +lat_0=18 +lon_0=-77 +k_0=1 +x_0=750000 +y_0=650000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3449 : return "+proj=utm +zone=17 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3450 : return "+proj=utm +zone=18 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3451 : return "+proj=lcc +lat_1=32.66666666666666 +lat_2=31.16666666666667 +lat_0=30.5 +lon_0=-92.5 +x_0=999999.9999898402 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3452 : return "+proj=lcc +lat_1=30.7 +lat_2=29.3 +lat_0=28.5 +lon_0=-91.33333333333333 +x_0=999999.9999898402 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3453 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.5 +lon_0=-91.33333333333333 +x_0=999999.9999898402 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3454 : return "+proj=lcc +lat_1=44.4 +lat_2=42.83333333333334 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3455 : return "+proj=lcc +lat_1=44.4 +lat_2=42.83333333333334 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3456 : return "+proj=lcc +lat_1=32.66666666666666 +lat_2=31.16666666666667 +lat_0=30.5 +lon_0=-92.5 +x_0=999999.9999898402 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3457 : return "+proj=lcc +lat_1=30.7 +lat_2=29.3 +lat_0=28.5 +lon_0=-91.33333333333333 +x_0=999999.9999898402 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3458 : return "+proj=lcc +lat_1=45.68333333333333 +lat_2=44.41666666666666 +lat_0=43.83333333333334 +lon_0=-100 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3459 : return "+proj=lcc +lat_1=44.4 +lat_2=42.83333333333334 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3460 : return "+proj=tmerc +lat_0=-17 +lon_0=178.75 +k=0.99985 +x_0=2000000 +y_0=4000000 +ellps=WGS72 +units=m";
+ case 3461 : return "+proj=utm +zone=28 +a=6378249.2 +b=6356515 +towgs84=-83,37,124,0,0,0,0 +units=m";
+ case 3462 : return "+proj=utm +zone=29 +a=6378249.2 +b=6356515 +towgs84=-83,37,124,0,0,0,0 +units=m";
+ case 3463 : return "+proj=tmerc +lat_0=43.5 +lon_0=-69.125 +k=0.99998 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3464 : return "+proj=tmerc +lat_0=43.5 +lon_0=-69.125 +k=0.99998 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 3465 : return "+proj=tmerc +lat_0=30.5 +lon_0=-85.83333333333333 +k=0.99996 +x_0=200000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3466 : return "+proj=tmerc +lat_0=30 +lon_0=-87.5 +k=0.999933333 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3467 : return "+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3468 : return "+proj=omerc +lat_0=57 +lonc=-133.6666666666667 +alpha=323.1301023611111 +k=0.9999 +x_0=5000000 +y_0=-5000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3469 : return "+proj=tmerc +lat_0=54 +lon_0=-142 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3470 : return "+proj=tmerc +lat_0=54 +lon_0=-146 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3471 : return "+proj=tmerc +lat_0=54 +lon_0=-150 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3472 : return "+proj=tmerc +lat_0=54 +lon_0=-154 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3473 : return "+proj=tmerc +lat_0=54 +lon_0=-158 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3474 : return "+proj=tmerc +lat_0=54 +lon_0=-162 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3475 : return "+proj=tmerc +lat_0=54 +lon_0=-166 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3476 : return "+proj=tmerc +lat_0=54 +lon_0=-170 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3477 : return "+proj=lcc +lat_1=53.83333333333334 +lat_2=51.83333333333334 +lat_0=51 +lon_0=-176 +x_0=1000000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3478 : return "+proj=tmerc +lat_0=31 +lon_0=-111.9166666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3479 : return "+proj=tmerc +lat_0=31 +lon_0=-111.9166666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3480 : return "+proj=tmerc +lat_0=31 +lon_0=-110.1666666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3481 : return "+proj=tmerc +lat_0=31 +lon_0=-110.1666666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3482 : return "+proj=tmerc +lat_0=31 +lon_0=-113.75 +k=0.999933333 +x_0=213360 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3483 : return "+proj=tmerc +lat_0=31 +lon_0=-113.75 +k=0.999933333 +x_0=213360 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3484 : return "+proj=lcc +lat_1=36.23333333333333 +lat_2=34.93333333333333 +lat_0=34.33333333333334 +lon_0=-92 +x_0=400000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3485 : return "+proj=lcc +lat_1=36.23333333333333 +lat_2=34.93333333333333 +lat_0=34.33333333333334 +lon_0=-92 +x_0=399999.99998984 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3486 : return "+proj=lcc +lat_1=34.76666666666667 +lat_2=33.3 +lat_0=32.66666666666666 +lon_0=-92 +x_0=400000 +y_0=400000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3487 : return "+proj=lcc +lat_1=34.76666666666667 +lat_2=33.3 +lat_0=32.66666666666666 +lon_0=-92 +x_0=399999.99998984 +y_0=399999.99998984 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3488 : return "+proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3489 : return "+proj=lcc +lat_1=41.66666666666666 +lat_2=40 +lat_0=39.33333333333334 +lon_0=-122 +x_0=2000000 +y_0=500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3490 : return "+proj=lcc +lat_1=41.66666666666666 +lat_2=40 +lat_0=39.33333333333334 +lon_0=-122 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3491 : return "+proj=lcc +lat_1=39.83333333333334 +lat_2=38.33333333333334 +lat_0=37.66666666666666 +lon_0=-122 +x_0=2000000 +y_0=500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3492 : return "+proj=lcc +lat_1=39.83333333333334 +lat_2=38.33333333333334 +lat_0=37.66666666666666 +lon_0=-122 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3493 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.06666666666667 +lat_0=36.5 +lon_0=-120.5 +x_0=2000000 +y_0=500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3494 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.06666666666667 +lat_0=36.5 +lon_0=-120.5 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3495 : return "+proj=lcc +lat_1=37.25 +lat_2=36 +lat_0=35.33333333333334 +lon_0=-119 +x_0=2000000 +y_0=500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3496 : return "+proj=lcc +lat_1=37.25 +lat_2=36 +lat_0=35.33333333333334 +lon_0=-119 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3497 : return "+proj=lcc +lat_1=35.46666666666667 +lat_2=34.03333333333333 +lat_0=33.5 +lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3498 : return "+proj=lcc +lat_1=35.46666666666667 +lat_2=34.03333333333333 +lat_0=33.5 +lon_0=-118 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3499 : return "+proj=lcc +lat_1=33.88333333333333 +lat_2=32.78333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=2000000 +y_0=500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3500 : return "+proj=lcc +lat_1=33.88333333333333 +lat_2=32.78333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3501 : return "+proj=lcc +lat_1=39.75 +lat_2=38.45 +lat_0=37.83333333333334 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3502 : return "+proj=lcc +lat_1=39.75 +lat_2=38.45 +lat_0=37.83333333333334 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3503 : return "+proj=lcc +lat_1=40.78333333333333 +lat_2=39.71666666666667 +lat_0=39.33333333333334 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3504 : return "+proj=lcc +lat_1=40.78333333333333 +lat_2=39.71666666666667 +lat_0=39.33333333333334 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3505 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.23333333333333 +lat_0=36.66666666666666 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3506 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.23333333333333 +lat_0=36.66666666666666 +lon_0=-105.5 +x_0=914401.8288036576 +y_0=304800.6096012192 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3507 : return "+proj=lcc +lat_1=41.86666666666667 +lat_2=41.2 +lat_0=40.83333333333334 +lon_0=-72.75 +x_0=304800.6096 +y_0=152400.3048 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3508 : return "+proj=lcc +lat_1=41.86666666666667 +lat_2=41.2 +lat_0=40.83333333333334 +lon_0=-72.75 +x_0=304800.6096012192 +y_0=152400.3048006096 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3509 : return "+proj=tmerc +lat_0=38 +lon_0=-75.41666666666667 +k=0.999995 +x_0=200000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3510 : return "+proj=tmerc +lat_0=38 +lon_0=-75.41666666666667 +k=0.999995 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3511 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-81 +k=0.999941177 +x_0=200000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3512 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-81 +k=0.999941177 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3513 : return "+proj=aea +lat_1=24 +lat_2=31.5 +lat_0=24 +lon_0=-84 +x_0=400000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3514 : return "+proj=lcc +lat_1=30.75 +lat_2=29.58333333333333 +lat_0=29 +lon_0=-84.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3515 : return "+proj=lcc +lat_1=30.75 +lat_2=29.58333333333333 +lat_0=29 +lon_0=-84.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3516 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-82 +k=0.999941177 +x_0=200000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3517 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-82 +k=0.999941177 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3518 : return "+proj=tmerc +lat_0=30 +lon_0=-82.16666666666667 +k=0.9999 +x_0=200000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3519 : return "+proj=tmerc +lat_0=30 +lon_0=-82.16666666666667 +k=0.9999 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3520 : return "+proj=tmerc +lat_0=30 +lon_0=-84.16666666666667 +k=0.9999 +x_0=700000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3521 : return "+proj=tmerc +lat_0=30 +lon_0=-84.16666666666667 +k=0.9999 +x_0=699999.9998983998 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3522 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-114 +k=0.9999473679999999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3523 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-114 +k=0.9999473679999999 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3524 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-112.1666666666667 +k=0.9999473679999999 +x_0=200000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3525 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-112.1666666666667 +k=0.9999473679999999 +x_0=200000.0001016002 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3526 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-115.75 +k=0.999933333 +x_0=800000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3527 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-115.75 +k=0.999933333 +x_0=800000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3528 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-88.33333333333333 +k=0.9999749999999999 +x_0=300000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3529 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-88.33333333333333 +k=0.9999749999999999 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3530 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-90.16666666666667 +k=0.999941177 +x_0=700000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3531 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-90.16666666666667 +k=0.999941177 +x_0=699999.9999898402 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3532 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=100000 +y_0=250000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3533 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=99999.99989839978 +y_0=249999.9998983998 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3534 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=900000 +y_0=250000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3535 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=900000 +y_0=249999.9998983998 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3536 : return "+proj=lcc +lat_1=43.26666666666667 +lat_2=42.06666666666667 +lat_0=41.5 +lon_0=-93.5 +x_0=1500000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3537 : return "+proj=lcc +lat_1=43.26666666666667 +lat_2=42.06666666666667 +lat_0=41.5 +lon_0=-93.5 +x_0=1500000 +y_0=999999.9999898402 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3538 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.61666666666667 +lat_0=40 +lon_0=-93.5 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3539 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.61666666666667 +lat_0=40 +lon_0=-93.5 +x_0=500000.00001016 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3540 : return "+proj=lcc +lat_1=39.78333333333333 +lat_2=38.71666666666667 +lat_0=38.33333333333334 +lon_0=-98 +x_0=400000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3541 : return "+proj=lcc +lat_1=39.78333333333333 +lat_2=38.71666666666667 +lat_0=38.33333333333334 +lon_0=-98 +x_0=399999.99998984 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3542 : return "+proj=lcc +lat_1=38.56666666666667 +lat_2=37.26666666666667 +lat_0=36.66666666666666 +lon_0=-98.5 +x_0=400000 +y_0=400000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3543 : return "+proj=lcc +lat_1=38.56666666666667 +lat_2=37.26666666666667 +lat_0=36.66666666666666 +lon_0=-98.5 +x_0=399999.99998984 +y_0=399999.99998984 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3544 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=38.96666666666667 +lat_0=37.5 +lon_0=-84.25 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3545 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=38.96666666666667 +lat_0=37.5 +lon_0=-84.25 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3546 : return "+proj=lcc +lat_1=37.08333333333334 +lat_2=38.66666666666666 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=1500000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3547 : return "+proj=lcc +lat_1=37.08333333333334 +lat_2=38.66666666666666 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=1500000 +y_0=999999.9998983998 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3548 : return "+proj=lcc +lat_1=37.93333333333333 +lat_2=36.73333333333333 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=500000 +y_0=500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3549 : return "+proj=lcc +lat_1=37.93333333333333 +lat_2=36.73333333333333 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=500000.0001016001 +y_0=500000.0001016001 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3550 : return "+proj=lcc +lat_1=32.66666666666666 +lat_2=31.16666666666667 +lat_0=30.5 +lon_0=-92.5 +x_0=1000000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3551 : return "+proj=lcc +lat_1=32.66666666666666 +lat_2=31.16666666666667 +lat_0=30.5 +lon_0=-92.5 +x_0=999999.9999898402 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3552 : return "+proj=lcc +lat_1=30.7 +lat_2=29.3 +lat_0=28.5 +lon_0=-91.33333333333333 +x_0=1000000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3553 : return "+proj=lcc +lat_1=30.7 +lat_2=29.3 +lat_0=28.5 +lon_0=-91.33333333333333 +x_0=999999.9999898402 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3554 : return "+proj=tmerc +lat_0=43.5 +lon_0=-69.125 +k=0.99998 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3555 : return "+proj=tmerc +lat_0=43.83333333333334 +lon_0=-67.875 +k=0.99998 +x_0=700000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3556 : return "+proj=tmerc +lat_0=42.83333333333334 +lon_0=-70.375 +k=0.99998 +x_0=300000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3557 : return "+proj=tmerc +lat_0=43.66666666666666 +lon_0=-68.5 +k=0.9999 +x_0=300000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3558 : return "+proj=tmerc +lat_0=42.83333333333334 +lon_0=-70.16666666666667 +k=0.999966667 +x_0=900000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3559 : return "+proj=lcc +lat_1=39.45 +lat_2=38.3 +lat_0=37.66666666666666 +lon_0=-77 +x_0=400000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3560 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000.00001016 +y_0=999999.9999898402 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3561 : return "+proj=tmerc +lat_0=18.83333333333333 +lon_0=-155.5 +k=0.999966667 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +to_meter=0.3048006096012192";
+ case 3562 : return "+proj=tmerc +lat_0=20.33333333333333 +lon_0=-156.6666666666667 +k=0.999966667 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +to_meter=0.3048006096012192";
+ case 3563 : return "+proj=tmerc +lat_0=21.16666666666667 +lon_0=-158 +k=0.99999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +to_meter=0.3048006096012192";
+ case 3564 : return "+proj=tmerc +lat_0=21.83333333333333 +lon_0=-159.5 +k=0.99999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +to_meter=0.3048006096012192";
+ case 3565 : return "+proj=tmerc +lat_0=21.66666666666667 +lon_0=-160.1666666666667 +k=1 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +to_meter=0.3048006096012192";
+ case 3566 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000.00001016 +y_0=2000000.00001016 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3567 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000.00001016 +y_0=3000000 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3568 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000.00001016 +y_0=999999.9999898402 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3569 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000.00001016 +y_0=2000000.00001016 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3570 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000.00001016 +y_0=3000000 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3571 : return "+proj=laea +lat_0=90 +lon_0=180 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3572 : return "+proj=laea +lat_0=90 +lon_0=-150 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3573 : return "+proj=laea +lat_0=90 +lon_0=-100 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3574 : return "+proj=laea +lat_0=90 +lon_0=-40 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3575 : return "+proj=laea +lat_0=90 +lon_0=10 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3576 : return "+proj=laea +lat_0=90 +lon_0=90 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3577 : return "+proj=aea +lat_1=-18 +lat_2=-36 +lat_0=0 +lon_0=132 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3578 : return "+proj=aea +lat_1=61.66666666666666 +lat_2=68 +lat_0=59 +lon_0=-132.5 +x_0=500000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3579 : return "+proj=aea +lat_1=61.66666666666666 +lat_2=68 +lat_0=59 +lon_0=-132.5 +x_0=500000 +y_0=500000 +ellps=GRS80 +units=m";
+ case 3580 : return "+proj=lcc +lat_1=62 +lat_2=70 +lat_0=0 +lon_0=-112 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 3581 : return "+proj=lcc +lat_1=62 +lat_2=70 +lat_0=0 +lon_0=-112 +x_0=0 +y_0=0 +ellps=GRS80 +units=m";
+ case 3582 : return "+proj=lcc +lat_1=39.45 +lat_2=38.3 +lat_0=37.66666666666666 +lon_0=-77 +x_0=399999.9998983998 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3583 : return "+proj=lcc +lat_1=41.48333333333333 +lat_2=41.28333333333333 +lat_0=41 +lon_0=-70.5 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3584 : return "+proj=lcc +lat_1=41.48333333333333 +lat_2=41.28333333333333 +lat_0=41 +lon_0=-70.5 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3585 : return "+proj=lcc +lat_1=42.68333333333333 +lat_2=41.71666666666667 +lat_0=41 +lon_0=-71.5 +x_0=200000 +y_0=750000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3586 : return "+proj=lcc +lat_1=42.68333333333333 +lat_2=41.71666666666667 +lat_0=41 +lon_0=-71.5 +x_0=200000.0001016002 +y_0=750000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3587 : return "+proj=lcc +lat_1=45.7 +lat_2=44.18333333333333 +lat_0=43.31666666666667 +lon_0=-84.36666666666666 +x_0=6000000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3588 : return "+proj=lcc +lat_1=45.7 +lat_2=44.18333333333333 +lat_0=43.31666666666667 +lon_0=-84.36666666666666 +x_0=5999999.999976001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3589 : return "+proj=lcc +lat_1=47.08333333333334 +lat_2=45.48333333333333 +lat_0=44.78333333333333 +lon_0=-87 +x_0=8000000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3590 : return "+proj=lcc +lat_1=47.08333333333334 +lat_2=45.48333333333333 +lat_0=44.78333333333333 +lon_0=-87 +x_0=7999999.999968001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3591 : return "+proj=omerc +lat_0=45.30916666666666 +lonc=-86 +alpha=337.25556 +k=0.9996 +x_0=2546731.496 +y_0=-4354009.816 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3592 : return "+proj=lcc +lat_1=43.66666666666666 +lat_2=42.1 +lat_0=41.5 +lon_0=-84.36666666666666 +x_0=4000000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3593 : return "+proj=lcc +lat_1=43.66666666666666 +lat_2=42.1 +lat_0=41.5 +lon_0=-84.36666666666666 +x_0=3999999.999984 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3594 : return "+proj=lcc +lat_1=47.05 +lat_2=45.61666666666667 +lat_0=45 +lon_0=-94.25 +x_0=800000 +y_0=100000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3595 : return "+proj=lcc +lat_1=48.63333333333333 +lat_2=47.03333333333333 +lat_0=46.5 +lon_0=-93.09999999999999 +x_0=800000 +y_0=100000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3596 : return "+proj=lcc +lat_1=45.21666666666667 +lat_2=43.78333333333333 +lat_0=43 +lon_0=-94 +x_0=800000 +y_0=100000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3597 : return "+proj=tmerc +lat_0=29.5 +lon_0=-88.83333333333333 +k=0.99995 +x_0=300000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3598 : return "+proj=tmerc +lat_0=29.5 +lon_0=-88.83333333333333 +k=0.99995 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3599 : return "+proj=tmerc +lat_0=29.5 +lon_0=-90.33333333333333 +k=0.99995 +x_0=700000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3600 : return "+proj=tmerc +lat_0=29.5 +lon_0=-90.33333333333333 +k=0.99995 +x_0=699999.9998983998 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3601 : return "+proj=tmerc +lat_0=35.83333333333334 +lon_0=-92.5 +k=0.999933333 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3602 : return "+proj=tmerc +lat_0=35.83333333333334 +lon_0=-90.5 +k=0.999933333 +x_0=250000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3603 : return "+proj=tmerc +lat_0=36.16666666666666 +lon_0=-94.5 +k=0.999941177 +x_0=850000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3604 : return "+proj=lcc +lat_1=49 +lat_2=45 +lat_0=44.25 +lon_0=-109.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3605 : return "+proj=lcc +lat_1=49 +lat_2=45 +lat_0=44.25 +lon_0=-109.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3606 : return "+proj=lcc +lat_1=43 +lat_2=40 +lat_0=39.83333333333334 +lon_0=-100 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3607 : return "+proj=tmerc +lat_0=34.75 +lon_0=-116.6666666666667 +k=0.9999 +x_0=500000 +y_0=6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3608 : return "+proj=tmerc +lat_0=34.75 +lon_0=-116.6666666666667 +k=0.9999 +x_0=500000.00001016 +y_0=6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3609 : return "+proj=tmerc +lat_0=34.75 +lon_0=-115.5833333333333 +k=0.9999 +x_0=200000 +y_0=8000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3610 : return "+proj=tmerc +lat_0=34.75 +lon_0=-115.5833333333333 +k=0.9999 +x_0=200000.00001016 +y_0=8000000.000010163 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3611 : return "+proj=tmerc +lat_0=34.75 +lon_0=-118.5833333333333 +k=0.9999 +x_0=800000 +y_0=4000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3612 : return "+proj=tmerc +lat_0=34.75 +lon_0=-118.5833333333333 +k=0.9999 +x_0=800000.0000101599 +y_0=3999999.99998984 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3613 : return "+proj=tmerc +lat_0=42.5 +lon_0=-71.66666666666667 +k=0.999966667 +x_0=300000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3614 : return "+proj=tmerc +lat_0=42.5 +lon_0=-71.66666666666667 +k=0.999966667 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3615 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3616 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3617 : return "+proj=tmerc +lat_0=31 +lon_0=-106.25 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3618 : return "+proj=tmerc +lat_0=31 +lon_0=-106.25 +k=0.9999 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3619 : return "+proj=tmerc +lat_0=31 +lon_0=-104.3333333333333 +k=0.999909091 +x_0=165000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3620 : return "+proj=tmerc +lat_0=31 +lon_0=-104.3333333333333 +k=0.999909091 +x_0=165000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3621 : return "+proj=tmerc +lat_0=31 +lon_0=-107.8333333333333 +k=0.999916667 +x_0=830000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3622 : return "+proj=tmerc +lat_0=31 +lon_0=-107.8333333333333 +k=0.999916667 +x_0=830000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3623 : return "+proj=tmerc +lat_0=40 +lon_0=-76.58333333333333 +k=0.9999375 +x_0=250000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3624 : return "+proj=tmerc +lat_0=40 +lon_0=-76.58333333333333 +k=0.9999375 +x_0=249999.9998983998 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3625 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3626 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3627 : return "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3628 : return "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3629 : return "+proj=tmerc +lat_0=40 +lon_0=-78.58333333333333 +k=0.9999375 +x_0=350000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3630 : return "+proj=tmerc +lat_0=40 +lon_0=-78.58333333333333 +k=0.9999375 +x_0=350000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3631 : return "+proj=lcc +lat_1=36.16666666666666 +lat_2=34.33333333333334 +lat_0=33.75 +lon_0=-79 +x_0=609601.22 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3632 : return "+proj=lcc +lat_1=36.16666666666666 +lat_2=34.33333333333334 +lat_0=33.75 +lon_0=-79 +x_0=609601.2192024384 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3633 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.43333333333333 +lat_0=47 +lon_0=-100.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3634 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.43333333333333 +lat_0=47 +lon_0=-100.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3635 : return "+proj=lcc +lat_1=47.48333333333333 +lat_2=46.18333333333333 +lat_0=45.66666666666666 +lon_0=-100.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3636 : return "+proj=lcc +lat_1=47.48333333333333 +lat_2=46.18333333333333 +lat_0=45.66666666666666 +lon_0=-100.5 +x_0=599999.9999976 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3637 : return "+proj=lcc +lat_1=41.7 +lat_2=40.43333333333333 +lat_0=39.66666666666666 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3638 : return "+proj=lcc +lat_1=40.03333333333333 +lat_2=38.73333333333333 +lat_0=38 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3639 : return "+proj=lcc +lat_1=36.76666666666667 +lat_2=35.56666666666667 +lat_0=35 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3640 : return "+proj=lcc +lat_1=36.76666666666667 +lat_2=35.56666666666667 +lat_0=35 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3641 : return "+proj=lcc +lat_1=35.23333333333333 +lat_2=33.93333333333333 +lat_0=33.33333333333334 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3642 : return "+proj=lcc +lat_1=35.23333333333333 +lat_2=33.93333333333333 +lat_0=33.33333333333334 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3643 : return "+proj=lcc +lat_1=43 +lat_2=45.5 +lat_0=41.75 +lon_0=-120.5 +x_0=400000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3644 : return "+proj=lcc +lat_1=43 +lat_2=45.5 +lat_0=41.75 +lon_0=-120.5 +x_0=399999.9999984 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3645 : return "+proj=lcc +lat_1=46 +lat_2=44.33333333333334 +lat_0=43.66666666666666 +lon_0=-120.5 +x_0=2500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3646 : return "+proj=lcc +lat_1=46 +lat_2=44.33333333333334 +lat_0=43.66666666666666 +lon_0=-120.5 +x_0=2500000.0001424 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3647 : return "+proj=lcc +lat_1=44 +lat_2=42.33333333333334 +lat_0=41.66666666666666 +lon_0=-120.5 +x_0=1500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3648 : return "+proj=lcc +lat_1=44 +lat_2=42.33333333333334 +lat_0=41.66666666666666 +lon_0=-120.5 +x_0=1500000.0001464 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3649 : return "+proj=lcc +lat_1=41.95 +lat_2=40.88333333333333 +lat_0=40.16666666666666 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3650 : return "+proj=lcc +lat_1=41.95 +lat_2=40.88333333333333 +lat_0=40.16666666666666 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3651 : return "+proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3652 : return "+proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3653 : return "+proj=tmerc +lat_0=41.08333333333334 +lon_0=-71.5 +k=0.99999375 +x_0=100000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3654 : return "+proj=tmerc +lat_0=41.08333333333334 +lon_0=-71.5 +k=0.99999375 +x_0=99999.99998983997 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3655 : return "+proj=lcc +lat_1=34.83333333333334 +lat_2=32.5 +lat_0=31.83333333333333 +lon_0=-81 +x_0=609600 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3656 : return "+proj=lcc +lat_1=34.83333333333334 +lat_2=32.5 +lat_0=31.83333333333333 +lon_0=-81 +x_0=609600 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3657 : return "+proj=lcc +lat_1=45.68333333333333 +lat_2=44.41666666666666 +lat_0=43.83333333333334 +lon_0=-100 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3658 : return "+proj=lcc +lat_1=45.68333333333333 +lat_2=44.41666666666666 +lat_0=43.83333333333334 +lon_0=-100 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3659 : return "+proj=lcc +lat_1=44.4 +lat_2=42.83333333333334 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3660 : return "+proj=lcc +lat_1=44.4 +lat_2=42.83333333333334 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3661 : return "+proj=lcc +lat_1=36.41666666666666 +lat_2=35.25 +lat_0=34.33333333333334 +lon_0=-86 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3662 : return "+proj=lcc +lat_1=36.41666666666666 +lat_2=35.25 +lat_0=34.33333333333334 +lon_0=-86 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3663 : return "+proj=lcc +lat_1=31.88333333333333 +lat_2=30.11666666666667 +lat_0=29.66666666666667 +lon_0=-100.3333333333333 +x_0=700000 +y_0=3000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3664 : return "+proj=lcc +lat_1=31.88333333333333 +lat_2=30.11666666666667 +lat_0=29.66666666666667 +lon_0=-100.3333333333333 +x_0=699999.9998983998 +y_0=3000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3665 : return "+proj=aea +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3666 : return "+proj=lcc +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=5000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3667 : return "+proj=lcc +lat_1=36.18333333333333 +lat_2=34.65 +lat_0=34 +lon_0=-101.5 +x_0=200000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3668 : return "+proj=lcc +lat_1=36.18333333333333 +lat_2=34.65 +lat_0=34 +lon_0=-101.5 +x_0=200000.0001016002 +y_0=999999.9998983998 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3669 : return "+proj=lcc +lat_1=33.96666666666667 +lat_2=32.13333333333333 +lat_0=31.66666666666667 +lon_0=-98.5 +x_0=600000 +y_0=2000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3670 : return "+proj=lcc +lat_1=33.96666666666667 +lat_2=32.13333333333333 +lat_0=31.66666666666667 +lon_0=-98.5 +x_0=600000 +y_0=2000000.0001016 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3671 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.66666666666667 +lon_0=-98.5 +x_0=300000 +y_0=5000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3672 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.66666666666667 +lon_0=-98.5 +x_0=300000.0000000001 +y_0=5000000.0001016 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3673 : return "+proj=lcc +lat_1=30.28333333333333 +lat_2=28.38333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=4000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3674 : return "+proj=lcc +lat_1=30.28333333333333 +lat_2=28.38333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=3999999.9998984 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3675 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000 +y_0=2000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3676 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000.0001504 +y_0=1999999.999992 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3677 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000.00001016 +y_0=2000000.00001016 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3678 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3679 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000.0001504 +y_0=999999.9999960001 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3680 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000.00001016 +y_0=999999.9999898402 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3681 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000 +y_0=3000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3682 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000.0001504 +y_0=2999999.999988 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048";
+ case 3683 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000.00001016 +y_0=3000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3684 : return "+proj=tmerc +lat_0=42.5 +lon_0=-72.5 +k=0.999964286 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3685 : return "+proj=lcc +lat_1=39.2 +lat_2=38.03333333333333 +lat_0=37.66666666666666 +lon_0=-78.5 +x_0=3500000 +y_0=2000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3686 : return "+proj=lcc +lat_1=39.2 +lat_2=38.03333333333333 +lat_0=37.66666666666666 +lon_0=-78.5 +x_0=3500000.0001016 +y_0=2000000.0001016 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3687 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=36.76666666666667 +lat_0=36.33333333333334 +lon_0=-78.5 +x_0=3500000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3688 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=36.76666666666667 +lat_0=36.33333333333334 +lon_0=-78.5 +x_0=3500000.0001016 +y_0=999999.9998983998 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3689 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.5 +lat_0=47 +lon_0=-120.8333333333333 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3690 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.5 +lat_0=47 +lon_0=-120.8333333333333 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3691 : return "+proj=lcc +lat_1=47.33333333333334 +lat_2=45.83333333333334 +lat_0=45.33333333333334 +lon_0=-120.5 +x_0=500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3692 : return "+proj=lcc +lat_1=47.33333333333334 +lat_2=45.83333333333334 +lat_0=45.33333333333334 +lon_0=-120.5 +x_0=500000.0001016001 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3693 : return "+proj=lcc +lat_1=40.25 +lat_2=39 +lat_0=38.5 +lon_0=-79.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3694 : return "+proj=lcc +lat_1=38.88333333333333 +lat_2=37.48333333333333 +lat_0=37 +lon_0=-81 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3695 : return "+proj=lcc +lat_1=45.5 +lat_2=44.25 +lat_0=43.83333333333334 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3696 : return "+proj=lcc +lat_1=45.5 +lat_2=44.25 +lat_0=43.83333333333334 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3697 : return "+proj=lcc +lat_1=46.76666666666667 +lat_2=45.56666666666667 +lat_0=45.16666666666666 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3698 : return "+proj=lcc +lat_1=46.76666666666667 +lat_2=45.56666666666667 +lat_0=45.16666666666666 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3699 : return "+proj=lcc +lat_1=44.06666666666667 +lat_2=42.73333333333333 +lat_0=42 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3700 : return "+proj=lcc +lat_1=44.06666666666667 +lat_2=42.73333333333333 +lat_0=42 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3701 : return "+proj=tmerc +lat_0=0 +lon_0=-90 +k=0.9996 +x_0=520000 +y_0=-4480000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3702 : return "+proj=tmerc +lat_0=40.5 +lon_0=-105.1666666666667 +k=0.9999375 +x_0=200000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3703 : return "+proj=tmerc +lat_0=40.5 +lon_0=-107.3333333333333 +k=0.9999375 +x_0=400000 +y_0=100000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3704 : return "+proj=tmerc +lat_0=40.5 +lon_0=-108.75 +k=0.9999375 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3705 : return "+proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +k=0.9999375 +x_0=800000 +y_0=100000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3706 : return "+proj=utm +zone=59 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3707 : return "+proj=utm +zone=60 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3708 : return "+proj=utm +zone=1 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3709 : return "+proj=utm +zone=2 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3710 : return "+proj=utm +zone=3 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3711 : return "+proj=utm +zone=4 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3712 : return "+proj=utm +zone=5 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3713 : return "+proj=utm +zone=6 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3714 : return "+proj=utm +zone=7 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3715 : return "+proj=utm +zone=8 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3716 : return "+proj=utm +zone=9 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3717 : return "+proj=utm +zone=10 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3718 : return "+proj=utm +zone=11 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3719 : return "+proj=utm +zone=12 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3720 : return "+proj=utm +zone=13 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3721 : return "+proj=utm +zone=14 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3722 : return "+proj=utm +zone=15 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3723 : return "+proj=utm +zone=16 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3724 : return "+proj=utm +zone=17 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3725 : return "+proj=utm +zone=18 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3726 : return "+proj=utm +zone=19 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 3727 : return "+proj=tmerc +lat_0=-21.11666666666667 +lon_0=55.53333333333333 +k=1 +x_0=160000 +y_0=50000 +ellps=intl +units=m";
+ case 3728 : return "+proj=lcc +lat_1=41.7 +lat_2=40.43333333333333 +lat_0=39.66666666666666 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3729 : return "+proj=lcc +lat_1=40.03333333333333 +lat_2=38.73333333333333 +lat_0=38 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3730 : return "+proj=tmerc +lat_0=40.5 +lon_0=-105.1666666666667 +k=0.9999375 +x_0=200000.00001016 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3731 : return "+proj=tmerc +lat_0=40.5 +lon_0=-107.3333333333333 +k=0.9999375 +x_0=399999.99998984 +y_0=99999.99998983997 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3732 : return "+proj=tmerc +lat_0=40.5 +lon_0=-108.75 +k=0.9999375 +x_0=600000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3733 : return "+proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +k=0.9999375 +x_0=800000.0000101599 +y_0=99999.99998983997 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3734 : return "+proj=lcc +lat_1=41.7 +lat_2=40.43333333333333 +lat_0=39.66666666666666 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3735 : return "+proj=lcc +lat_1=40.03333333333333 +lat_2=38.73333333333333 +lat_0=38 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3736 : return "+proj=tmerc +lat_0=40.5 +lon_0=-105.1666666666667 +k=0.9999375 +x_0=200000.00001016 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3737 : return "+proj=tmerc +lat_0=40.5 +lon_0=-107.3333333333333 +k=0.9999375 +x_0=399999.99998984 +y_0=99999.99998983997 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3738 : return "+proj=tmerc +lat_0=40.5 +lon_0=-108.75 +k=0.9999375 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3739 : return "+proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +k=0.9999375 +x_0=800000.0000101599 +y_0=99999.99998983997 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3740 : return "+proj=utm +zone=10 +ellps=GRS80 +units=m";
+ case 3741 : return "+proj=utm +zone=11 +ellps=GRS80 +units=m";
+ case 3742 : return "+proj=utm +zone=12 +ellps=GRS80 +units=m";
+ case 3743 : return "+proj=utm +zone=13 +ellps=GRS80 +units=m";
+ case 3744 : return "+proj=utm +zone=14 +ellps=GRS80 +units=m";
+ case 3745 : return "+proj=utm +zone=15 +ellps=GRS80 +units=m";
+ case 3746 : return "+proj=utm +zone=16 +ellps=GRS80 +units=m";
+ case 3747 : return "+proj=utm +zone=17 +ellps=GRS80 +units=m";
+ case 3748 : return "+proj=utm +zone=18 +ellps=GRS80 +units=m";
+ case 3749 : return "+proj=utm +zone=19 +ellps=GRS80 +units=m";
+ case 3750 : return "+proj=utm +zone=4 +ellps=GRS80 +units=m";
+ case 3751 : return "+proj=utm +zone=5 +ellps=GRS80 +units=m";
+ case 3752 : return "+proj=merc +lon_0=100 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3753 : return "+proj=lcc +lat_1=41.7 +lat_2=40.43333333333333 +lat_0=39.66666666666666 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3754 : return "+proj=lcc +lat_1=40.03333333333333 +lat_2=38.73333333333333 +lat_0=38 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3755 : return "+proj=tmerc +lat_0=40.5 +lon_0=-105.1666666666667 +k=0.9999375 +x_0=200000.00001016 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3756 : return "+proj=tmerc +lat_0=40.5 +lon_0=-107.3333333333333 +k=0.9999375 +x_0=399999.99998984 +y_0=99999.99998983997 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3757 : return "+proj=tmerc +lat_0=40.5 +lon_0=-108.75 +k=0.9999375 +x_0=600000 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3758 : return "+proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +k=0.9999375 +x_0=800000.0000101599 +y_0=99999.99998983997 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3759 : return "+proj=tmerc +lat_0=21.16666666666667 +lon_0=-158 +k=0.99999 +x_0=500000.00001016 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 3760 : return "+proj=tmerc +lat_0=21.16666666666667 +lon_0=-158 +k=0.99999 +x_0=500000.00001016 +y_0=0 +ellps=GRS80 +to_meter=0.3048006096012192";
+ case 3761 : return "+proj=utm +zone=22 +ellps=GRS80 +units=m";
+ case 3762 : return "+proj=lcc +lat_1=-54 +lat_2=-54.75 +lat_0=-55 +lon_0=-37 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 3920 : return "+proj=utm +zone=20 +ellps=clrk66 +towgs84=11,72,-101,0,0,0,0 +units=m";
+ case 3991 : return "+proj=lcc +lat_1=18.43333333333333 +lat_2=18.03333333333333 +lat_0=17.83333333333333 +lon_0=-66.43333333333334 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +towgs84=11,72,-101,0,0,0,0 +to_meter=0.3048006096012192";
+ case 3992 : return "+proj=lcc +lat_1=18.43333333333333 +lat_2=18.03333333333333 +lat_0=17.83333333333333 +lon_0=-66.43333333333334 +x_0=152400.3048006096 +y_0=30480.06096012192 +ellps=clrk66 +towgs84=11,72,-101,0,0,0,0 +to_meter=0.3048006096012192";
+ case 4001 : return "+proj=longlat +ellps=airy";
+ case 4002 : return "+proj=longlat +a=6377340.189 +b=6356034.447938534";
+ case 4003 : return "+proj=longlat +ellps=aust_SA";
+ case 4004 : return "+proj=longlat +ellps=bessel";
+ case 4005 : return "+proj=longlat +a=6377492.018 +b=6356173.508712696";
+ case 4006 : return "+proj=longlat +ellps=bess_nam";
+ case 4007 : return "+proj=longlat +a=6378293.645208759 +b=6356617.987679838";
+ case 4008 : return "+proj=longlat +ellps=clrk66";
+ case 4009 : return "+proj=longlat +a=6378450.047548896 +b=6356826.621488444";
+ case 4010 : return "+proj=longlat +a=6378300.789 +b=6356566.435";
+ case 4011 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4012 : return "+proj=longlat +ellps=clrk80";
+ case 4013 : return "+proj=longlat +a=6378249.145 +b=6356514.966398753";
+ case 4014 : return "+proj=longlat +a=6378249.2 +b=6356514.996941779";
+ case 4015 : return "+proj=longlat +a=6377276.345 +b=6356075.41314024";
+ case 4016 : return "+proj=longlat +ellps=evrstSS";
+ case 4018 : return "+proj=longlat +a=6377304.063 +b=6356103.038993155";
+ case 4019 : return "+proj=longlat +ellps=GRS80";
+ case 4020 : return "+proj=longlat +ellps=helmert";
+ case 4021 : return "+proj=longlat +a=6378160 +b=6356774.50408554";
+ case 4022 : return "+proj=longlat +ellps=intl";
+ case 4024 : return "+proj=longlat +ellps=krass";
+ case 4025 : return "+proj=longlat +ellps=WGS66";
+ case 4027 : return "+proj=longlat +a=6376523 +b=6355862.933255573";
+ case 4028 : return "+proj=longlat +a=6378298.3 +b=6356657.142669561";
+ case 4029 : return "+proj=longlat +a=6378300 +b=6356751.689189189";
+ case 4030 : return "+proj=longlat +ellps=WGS84";
+ case 4031 : return "+proj=longlat +ellps=WGS84";
+ case 4032 : return "+proj=longlat +a=6378136.2 +b=6356751.516927429";
+ case 4033 : return "+proj=longlat +a=6378136.3 +b=6356751.616592146";
+ case 4034 : return "+proj=longlat +ellps=clrk80";
+ case 4035 : return "+proj=longlat +a=6371000 +b=6371000";
+ case 4036 : return "+proj=longlat +ellps=GRS67";
+ case 4041 : return "+proj=longlat +a=6378135 +b=6356750.304921594";
+ case 4042 : return "+proj=longlat +a=6377299.36559538 +b=6356098.357204818";
+ case 4043 : return "+proj=longlat +ellps=WGS72";
+ case 4044 : return "+proj=longlat +a=6377301.243 +b=6356100.230165384";
+ case 4045 : return "+proj=longlat +a=6377299.151 +b=6356098.145120132";
+ case 4047 : return "+proj=longlat +a=6371007 +b=6371007";
+ case 4052 : return "+proj=longlat +a=6370997 +b=6370997";
+ case 4053 : return "+proj=longlat +a=6371228 +b=6371228";
+ case 4054 : return "+proj=longlat +a=6378273 +b=6356889.449";
+ case 4120 : return "+proj=longlat +ellps=bessel";
+ case 4121 : return "+proj=longlat +ellps=GRS80 +towgs84=-199.87,74.79,246.62,0,0,0,0";
+ case 4122 : return "+proj=longlat +a=6378135 +b=6356750.304921594";
+ case 4123 : return "+proj=longlat +ellps=intl +towgs84=-96.0617,-82.4278,-121.743,4.80107,0.34543,-1.37646,1.4964";
+ case 4124 : return "+proj=longlat +ellps=bessel";
+ case 4125 : return "+proj=longlat +ellps=bessel +towgs84=-404.78,685.68,45.47,0,0,0,0";
+ case 4126 : return "+proj=longlat +ellps=GRS80";
+ case 4127 : return "+proj=longlat +ellps=clrk66";
+ case 4128 : return "+proj=longlat +ellps=clrk66";
+ case 4129 : return "+proj=longlat +ellps=clrk66";
+ case 4130 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,-0,-0,-0,0";
+ case 4131 : return "+proj=longlat +a=6377276.345 +b=6356075.41314024";
+ case 4132 : return "+proj=longlat +ellps=clrk80";
+ case 4133 : return "+proj=longlat +ellps=GRS80 +towgs84=0.055,-0.541,-0.185,0.0183,-0.0003,-0.007,-0.014";
+ case 4134 : return "+proj=longlat +ellps=clrk80";
+ case 4135 : return "+proj=longlat +ellps=clrk66";
+ case 4136 : return "+proj=longlat +ellps=clrk66";
+ case 4137 : return "+proj=longlat +ellps=clrk66";
+ case 4138 : return "+proj=longlat +ellps=clrk66";
+ case 4139 : return "+proj=longlat +ellps=clrk66 +towgs84=11,72,-101,0,0,0,0";
+ case 4140 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4141 : return "+proj=longlat +ellps=GRS80 +towgs84=-48,55,52,0,0,0,0";
+ case 4142 : return "+proj=longlat +ellps=clrk80 +towgs84=-125,53,467,0,0,0,0";
+ case 4143 : return "+proj=longlat +ellps=clrk80 +towgs84=-124.76,53,466.79,0,0,0,0";
+ case 4144 : return "+proj=longlat +a=6377276.345 +b=6356075.41314024";
+ case 4145 : return "+proj=longlat +a=6377301.243 +b=6356100.230165384";
+ case 4146 : return "+proj=longlat +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0";
+ case 4147 : return "+proj=longlat +ellps=krass +towgs84=-17.51,-108.32,-62.39,0,0,0,0";
+ case 4148 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0";
+ case 4149 : return "+proj=longlat +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0";
+ case 4150 : return "+proj=longlat +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0";
+ case 4151 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4152 : return "+proj=longlat +ellps=GRS80";
+ case 4153 : return "+proj=longlat +ellps=intl +towgs84=-133.63,-157.5,-158.62,0,0,0,0";
+ case 4154 : return "+proj=longlat +ellps=intl";
+ case 4155 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=-83,37,124,0,0,0,0";
+ case 4156 : return "+proj=longlat +ellps=bessel";
+ case 4157 : return "+proj=longlat +a=6378293.645208759 +b=6356617.987679838";
+ case 4158 : return "+proj=longlat +ellps=intl";
+ case 4159 : return "+proj=longlat +ellps=intl";
+ case 4160 : return "+proj=longlat +ellps=intl";
+ case 4161 : return "+proj=longlat +ellps=intl +towgs84=27.5,14,186.4,0,0,0,0";
+ case 4162 : return "+proj=longlat +ellps=bessel";
+ case 4163 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0";
+ case 4164 : return "+proj=longlat +ellps=krass +towgs84=-76,-138,67,0,0,0,0";
+ case 4165 : return "+proj=longlat +ellps=intl +towgs84=-173,253,27,0,0,0,0";
+ case 4166 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0";
+ case 4167 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4168 : return "+proj=longlat +a=6378300 +b=6356751.689189189 +towgs84=-199,32,322,0,0,0,0";
+ case 4169 : return "+proj=longlat +ellps=clrk66 +towgs84=-115,118,426,0,0,0,0";
+ case 4170 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4171 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4172 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4173 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4174 : return "+proj=longlat +a=6378300 +b=6356751.689189189";
+ case 4175 : return "+proj=longlat +ellps=clrk80 +towgs84=-88,4,101,0,0,0,0";
+ case 4176 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4178 : return "+proj=longlat +ellps=krass +towgs84=24,-123,-94,0.02,-0.25,-0.13,1.1";
+ case 4179 : return "+proj=longlat +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84";
+ case 4180 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4181 : return "+proj=longlat +ellps=intl +towgs84=-193,13.7,-39.3,-0.41,-2.933,2.688,0.43";
+ case 4182 : return "+proj=longlat +ellps=intl";
+ case 4183 : return "+proj=longlat +ellps=intl +towgs84=-104,167,-38,0,0,0,0";
+ case 4184 : return "+proj=longlat +ellps=intl +towgs84=-203,141,53,0,0,0,0";
+ case 4185 : return "+proj=longlat +ellps=intl";
+ case 4188 : return "+proj=longlat +ellps=airy +towgs84=482.5,-130.6,564.6,-1.042,-0.214,-0.631,8.15";
+ case 4189 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4190 : return "+proj=longlat +ellps=GRS80";
+ case 4191 : return "+proj=longlat +ellps=krass";
+ case 4192 : return "+proj=longlat +ellps=intl +towgs84=-206.1,-174.7,-87.7,0,0,0,0";
+ case 4193 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=-70.9,-151.8,-41.4,0,0,0,0";
+ case 4194 : return "+proj=longlat +ellps=intl";
+ case 4195 : return "+proj=longlat +ellps=intl +towgs84=105,326,-102.5,0,0,0.814,-0.6";
+ case 4196 : return "+proj=longlat +ellps=intl +towgs84=-45,417,-3.5,0,0,0.814,-0.6";
+ case 4197 : return "+proj=longlat +ellps=clrk80";
+ case 4198 : return "+proj=longlat +ellps=clrk80";
+ case 4199 : return "+proj=longlat +ellps=intl";
+ case 4200 : return "+proj=longlat +ellps=krass";
+ case 4201 : return "+proj=longlat +ellps=clrk80";
+ case 4202 : return "+proj=longlat +ellps=aust_SA";
+ case 4203 : return "+proj=longlat +ellps=aust_SA";
+ case 4204 : return "+proj=longlat +ellps=intl";
+ case 4205 : return "+proj=longlat +ellps=krass +towgs84=-43,-163,45,0,0,0,0";
+ case 4206 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4207 : return "+proj=longlat +ellps=intl";
+ case 4208 : return "+proj=longlat +ellps=intl";
+ case 4209 : return "+proj=longlat +a=6378249.145 +b=6356514.966398753";
+ case 4210 : return "+proj=longlat +ellps=clrk80";
+ case 4211 : return "+proj=longlat +ellps=bessel";
+ case 4212 : return "+proj=longlat +ellps=clrk80 +towgs84=31.95,300.99,419.19,0,0,0,0";
+ case 4213 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=-106,-87,188,0,0,0,0";
+ case 4214 : return "+proj=longlat +ellps=krass";
+ case 4215 : return "+proj=longlat +ellps=intl";
+ case 4216 : return "+proj=longlat +ellps=clrk66 +towgs84=-73,213,296,0,0,0,0";
+ case 4218 : return "+proj=longlat +ellps=intl +towgs84=307,304,-318,0,0,0,0";
+ case 4219 : return "+proj=longlat +ellps=bessel +towgs84=-384,664,-48,0,0,0,0";
+ case 4220 : return "+proj=longlat +ellps=clrk80";
+ case 4221 : return "+proj=longlat +ellps=intl";
+ case 4222 : return "+proj=longlat +a=6378249.145 +b=6356514.966398753";
+ case 4223 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4224 : return "+proj=longlat +ellps=intl +towgs84=-134,229,-29,0,0,0,0";
+ case 4225 : return "+proj=longlat +ellps=intl +towgs84=-206,172,-6,0,0,0,0";
+ case 4226 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4227 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4228 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4229 : return "+proj=longlat +ellps=helmert";
+ case 4230 : return "+proj=longlat +ellps=intl";
+ case 4231 : return "+proj=longlat +ellps=intl";
+ case 4232 : return "+proj=longlat +ellps=clrk80";
+ case 4233 : return "+proj=longlat +ellps=intl +towgs84=-133,-321,50,0,0,0,0";
+ case 4234 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4235 : return "+proj=longlat +ellps=intl";
+ case 4236 : return "+proj=longlat +ellps=intl +towgs84=-637,-549,-203,0,0,0,0";
+ case 4237 : return "+proj=longlat +ellps=GRS67";
+ case 4238 : return "+proj=longlat +a=6378160 +b=6356774.50408554";
+ case 4239 : return "+proj=longlat +a=6377276.345 +b=6356075.41314024 +towgs84=217,823,299,0,0,0,0";
+ case 4240 : return "+proj=longlat +a=6377276.345 +b=6356075.41314024";
+ case 4241 : return "+proj=longlat +ellps=clrk80";
+ case 4242 : return "+proj=longlat +ellps=clrk66";
+ case 4243 : return "+proj=longlat +a=6377299.36559538 +b=6356098.357204818";
+ case 4244 : return "+proj=longlat +a=6377276.345 +b=6356075.41314024 +towgs84=-97,787,86,0,0,0,0";
+ case 4245 : return "+proj=longlat +a=6377304.063 +b=6356103.038993155 +towgs84=-11,851,5,0,0,0,0";
+ case 4246 : return "+proj=longlat +ellps=clrk80 +towgs84=-294.7,-200.1,525.5,0,0,0,0";
+ case 4247 : return "+proj=longlat +ellps=intl +towgs84=-273.5,110.6,-357.9,0,0,0,0";
+ case 4248 : return "+proj=longlat +ellps=intl";
+ case 4249 : return "+proj=longlat +ellps=intl";
+ case 4250 : return "+proj=longlat +ellps=clrk80 +towgs84=-130,29,364,0,0,0,0";
+ case 4251 : return "+proj=longlat +ellps=clrk80 +towgs84=-90,40,88,0,0,0,0";
+ case 4252 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4253 : return "+proj=longlat +ellps=clrk66";
+ case 4254 : return "+proj=longlat +ellps=intl";
+ case 4255 : return "+proj=longlat +ellps=intl +towgs84=-333,-222,114,0,0,0,0";
+ case 4256 : return "+proj=longlat +ellps=clrk80 +towgs84=41,-220,-134,0,0,0,0";
+ case 4257 : return "+proj=longlat +ellps=bessel +towgs84=-587.8,519.75,145.76,0,0,0,0";
+ case 4258 : return "+proj=longlat +ellps=GRS80";
+ case 4259 : return "+proj=longlat +ellps=intl";
+ case 4260 : return "+proj=longlat +ellps=clrk80 +towgs84=-70.9,-151.8,-41.4,0,0,0,0";
+ case 4261 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=31,146,47,0,0,0,0";
+ case 4262 : return "+proj=longlat +ellps=bessel +towgs84=639,405,60,0,0,0,0";
+ case 4263 : return "+proj=longlat +ellps=clrk80";
+ case 4264 : return "+proj=longlat +ellps=intl +towgs84=-252.95,-4.11,-96.38,0,0,0,0";
+ case 4265 : return "+proj=longlat +ellps=intl";
+ case 4266 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4267 : return "+proj=longlat +ellps=clrk66 +datum=NAD27";
+ case 4268 : return "+proj=longlat +a=6378450.047548896 +b=6356826.621488444";
+ case 4269 : return "+proj=longlat +ellps=GRS80 +datum=NAD83";
+ case 4270 : return "+proj=longlat +ellps=clrk80";
+ case 4271 : return "+proj=longlat +ellps=intl";
+ case 4272 : return "+proj=longlat +ellps=intl +datum=nzgd49";
+ case 4273 : return "+proj=longlat +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21";
+ case 4274 : return "+proj=longlat +ellps=intl";
+ case 4275 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0";
+ case 4276 : return "+proj=longlat +ellps=WGS66";
+ case 4277 : return "+proj=longlat +ellps=airy +datum=OSGB36";
+ case 4278 : return "+proj=longlat +ellps=airy";
+ case 4279 : return "+proj=longlat +ellps=airy";
+ case 4280 : return "+proj=longlat +ellps=bessel";
+ case 4281 : return "+proj=longlat +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1";
+ case 4282 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4283 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4284 : return "+proj=longlat +ellps=krass";
+ case 4285 : return "+proj=longlat +ellps=intl";
+ case 4286 : return "+proj=longlat +ellps=helmert";
+ case 4287 : return "+proj=longlat +ellps=intl +towgs84=164,138,-189,0,0,0,0";
+ case 4288 : return "+proj=longlat +ellps=intl";
+ case 4289 : return "+proj=longlat +ellps=bessel";
+ case 4291 : return "+proj=longlat +ellps=GRS67";
+ case 4292 : return "+proj=longlat +ellps=intl +towgs84=-355,21,72,0,0,0,0";
+ case 4293 : return "+proj=longlat +ellps=bess_nam";
+ case 4294 : return "+proj=longlat +ellps=bessel";
+ case 4295 : return "+proj=longlat +ellps=bessel";
+ case 4296 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4297 : return "+proj=longlat +ellps=intl +towgs84=-189,-242,-91,0,0,0,0";
+ case 4298 : return "+proj=longlat +ellps=evrstSS";
+ case 4299 : return "+proj=longlat +a=6377340.189 +b=6356034.447938534";
+ case 4300 : return "+proj=longlat +a=6377340.189 +b=6356034.447938534";
+ case 4301 : return "+proj=longlat +ellps=bessel";
+ case 4302 : return "+proj=longlat +a=6378293.645208759 +b=6356617.987679838";
+ case 4303 : return "+proj=longlat +ellps=helmert";
+ case 4304 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=-73,-247,227,0,0,0,0";
+ case 4306 : return "+proj=longlat +ellps=bessel";
+ case 4307 : return "+proj=longlat +ellps=clrk80";
+ case 4308 : return "+proj=longlat +ellps=bessel";
+ case 4309 : return "+proj=longlat +ellps=intl +towgs84=-155,171,37,0,0,0,0";
+ case 4310 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4311 : return "+proj=longlat +ellps=intl +towgs84=-265,120,-358,0,0,0,0";
+ case 4312 : return "+proj=longlat +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232";
+ case 4313 : return "+proj=longlat +ellps=intl +towgs84=106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1";
+ case 4314 : return "+proj=longlat +ellps=bessel +datum=potsdam";
+ case 4315 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0";
+ case 4316 : return "+proj=longlat +ellps=intl";
+ case 4317 : return "+proj=longlat +ellps=krass";
+ case 4318 : return "+proj=longlat +ellps=WGS84 +towgs84=-3.2,-5.7,2.8,0,0,0,0";
+ case 4319 : return "+proj=longlat +ellps=GRS80";
+ case 4322 : return "+proj=longlat +ellps=WGS72";
+ case 4324 : return "+proj=longlat +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38";
+ case 4326 : return "+proj=longlat +ellps=WGS84 +datum=WGS84";
+ case 4600 : return "+proj=longlat +ellps=clrk80";
+ case 4601 : return "+proj=longlat +ellps=clrk80";
+ case 4602 : return "+proj=longlat +ellps=clrk80 +towgs84=725,685,536,0,0,0,0";
+ case 4603 : return "+proj=longlat +ellps=clrk80 +towgs84=72,213.7,93,0,0,0,0";
+ case 4604 : return "+proj=longlat +ellps=clrk80 +towgs84=174,359,365,0,0,0,0";
+ case 4605 : return "+proj=longlat +ellps=clrk80";
+ case 4606 : return "+proj=longlat +ellps=clrk80 +towgs84=-149,128,296,0,0,0,0";
+ case 4607 : return "+proj=longlat +ellps=clrk80 +towgs84=195.671,332.517,274.607,0,0,0,0";
+ case 4608 : return "+proj=longlat +ellps=clrk66";
+ case 4609 : return "+proj=longlat +ellps=clrk66";
+ case 4610 : return "+proj=longlat +a=6378140 +b=6356755.288157528";
+ case 4611 : return "+proj=longlat +ellps=intl +towgs84=-162.619,-276.959,-161.764,0.067753,-2.24365,-1.15883,-1.09425";
+ case 4612 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4613 : return "+proj=longlat +ellps=bessel";
+ case 4614 : return "+proj=longlat +ellps=intl +towgs84=-119.425,-303.659,-11.0006,1.1643,0.174458,1.09626,3.65706";
+ case 4615 : return "+proj=longlat +ellps=intl +towgs84=-499,-249,314,0,0,0,0";
+ case 4616 : return "+proj=longlat +ellps=intl";
+ case 4617 : return "+proj=longlat +ellps=GRS80";
+ case 4618 : return "+proj=longlat +ellps=aust_SA";
+ case 4619 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4620 : return "+proj=longlat +ellps=clrk80 +towgs84=-106,-129,165,0,0,0,0";
+ case 4621 : return "+proj=longlat +ellps=intl +towgs84=137,248,-430,0,0,0,0";
+ case 4622 : return "+proj=longlat +ellps=intl";
+ case 4623 : return "+proj=longlat +ellps=intl +towgs84=-186,230,110,0,0,0,0";
+ case 4624 : return "+proj=longlat +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0";
+ case 4625 : return "+proj=longlat +ellps=intl";
+ case 4626 : return "+proj=longlat +ellps=intl";
+ case 4627 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4628 : return "+proj=longlat +ellps=intl +towgs84=162,117,154,0,0,0,0";
+ case 4629 : return "+proj=longlat +ellps=intl";
+ case 4630 : return "+proj=longlat +ellps=intl";
+ case 4631 : return "+proj=longlat +ellps=intl +towgs84=145,-187,103,0,0,0,0";
+ case 4632 : return "+proj=longlat +ellps=intl +towgs84=-382,-59,-262,0,0,0,0";
+ case 4633 : return "+proj=longlat +ellps=intl";
+ case 4634 : return "+proj=longlat +ellps=intl";
+ case 4635 : return "+proj=longlat +ellps=intl +towgs84=-122.383,-188.696,103.344,3.5107,-4.9668,-5.7047,4.4798";
+ case 4636 : return "+proj=longlat +ellps=intl +towgs84=365,194,166,0,0,0,0";
+ case 4637 : return "+proj=longlat +ellps=intl +towgs84=325,154,172,0,0,0,0";
+ case 4638 : return "+proj=longlat +ellps=clrk66 +towgs84=30,430,368,0,0,0,0";
+ case 4639 : return "+proj=longlat +ellps=intl";
+ case 4640 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0";
+ case 4641 : return "+proj=longlat +ellps=intl";
+ case 4642 : return "+proj=longlat +ellps=intl";
+ case 4643 : return "+proj=longlat +ellps=intl +towgs84=-480.26,-438.32,-643.429,16.3119,20.1721,-4.0349,-111.7";
+ case 4644 : return "+proj=longlat +ellps=intl";
+ case 4645 : return "+proj=longlat +ellps=intl +towgs84=0,0,0,0,0,0,0";
+ case 4646 : return "+proj=longlat +ellps=intl";
+ case 4657 : return "+proj=longlat +a=6377019.27 +b=6355762.5391 +towgs84=-28,199,5,0,0,0,0";
+ case 4658 : return "+proj=longlat +ellps=intl +towgs84=-73,46,-86,0,0,0,0";
+ case 4659 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4660 : return "+proj=longlat +ellps=intl +towgs84=982.609,552.753,-540.873,32.3934,-153.257,-96.2266,16.805";
+ case 4661 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4662 : return "+proj=longlat +ellps=intl";
+ case 4663 : return "+proj=longlat +ellps=intl";
+ case 4664 : return "+proj=longlat +ellps=intl";
+ case 4665 : return "+proj=longlat +ellps=intl";
+ case 4666 : return "+proj=longlat +ellps=bessel";
+ case 4667 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0";
+ case 4668 : return "+proj=longlat +ellps=intl +towgs84=-86,-98,-119,0,0,0,0";
+ case 4669 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4670 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0";
+ case 4671 : return "+proj=longlat +a=6378249.2 +b=6356515";
+ case 4672 : return "+proj=longlat +ellps=intl +towgs84=175,-38,113,0,0,0,0";
+ case 4673 : return "+proj=longlat +ellps=intl +towgs84=174.05,-25.49,112.57,-0,-0,0.554,0.2263";
+ case 4674 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4675 : return "+proj=longlat +ellps=clrk66 +towgs84=-100,-248,259,0,0,0,0";
+ case 4676 : return "+proj=longlat +ellps=krass";
+ case 4677 : return "+proj=longlat +ellps=krass";
+ case 4678 : return "+proj=longlat +ellps=krass +towgs84=44.585,-131.212,-39.544,0,0,0,0";
+ case 4679 : return "+proj=longlat +ellps=clrk80 +towgs84=-80.01,253.26,291.19,0,0,0,0";
+ case 4680 : return "+proj=longlat +ellps=clrk80 +towgs84=124.5,-63.5,-281,0,0,0,0";
+ case 4681 : return "+proj=longlat +ellps=clrk80";
+ case 4682 : return "+proj=longlat +a=6377276.345 +b=6356075.41314024";
+ case 4683 : return "+proj=longlat +ellps=clrk66 +towgs84=-127.62,-67.24,-47.04,-3.068,4.903,1.578,-1.06";
+ case 4684 : return "+proj=longlat +ellps=intl +towgs84=-133,-321,50,0,0,0,0";
+ case 4685 : return "+proj=longlat +ellps=intl";
+ case 4686 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4687 : return "+proj=longlat +ellps=GRS80";
+ case 4688 : return "+proj=longlat +ellps=intl +towgs84=347.103,1078.12,2623.92,-33.8875,70.6773,-9.3943,186.074";
+ case 4689 : return "+proj=longlat +ellps=intl";
+ case 4690 : return "+proj=longlat +ellps=intl";
+ case 4691 : return "+proj=longlat +ellps=intl +towgs84=215.525,149.593,176.229,-3.2624,-1.692,-1.1571,10.4773";
+ case 4692 : return "+proj=longlat +ellps=intl +towgs84=217.037,86.959,23.956,0,0,0,0";
+ case 4693 : return "+proj=longlat +ellps=WGS84 +towgs84=0,-0.15,0.68,0,0,0,0";
+ case 4694 : return "+proj=longlat +ellps=GRS80";
+ case 4695 : return "+proj=longlat +ellps=clrk66";
+ case 4696 : return "+proj=longlat +ellps=clrk80";
+ case 4697 : return "+proj=longlat +ellps=clrk80";
+ case 4698 : return "+proj=longlat +ellps=intl +towgs84=145,-187,103,0,0,0,0";
+ case 4699 : return "+proj=longlat +ellps=clrk80 +towgs84=-770.1,158.4,-498.2,0,0,0,0";
+ case 4700 : return "+proj=longlat +ellps=clrk80";
+ case 4701 : return "+proj=longlat +ellps=clrk80 +towgs84=-79.9,-158,-168.9,0,0,0,0";
+ case 4702 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4703 : return "+proj=longlat +ellps=clrk80";
+ case 4704 : return "+proj=longlat +ellps=intl";
+ case 4705 : return "+proj=longlat +ellps=intl";
+ case 4706 : return "+proj=longlat +ellps=helmert +towgs84=-146.21,112.63,4.05,0,0,0,0";
+ case 4707 : return "+proj=longlat +ellps=intl +towgs84=114,-116,-333,0,0,0,0";
+ case 4708 : return "+proj=longlat +ellps=aust_SA +towgs84=-491,-22,435,0,0,0,0";
+ case 4709 : return "+proj=longlat +ellps=intl +towgs84=145,75,-272,0,0,0,0";
+ case 4710 : return "+proj=longlat +ellps=intl +towgs84=-320,550,-494,0,0,0,0";
+ case 4711 : return "+proj=longlat +ellps=intl +towgs84=124,-234,-25,0,0,0,0";
+ case 4712 : return "+proj=longlat +ellps=intl +towgs84=-205,107,53,0,0,0,0";
+ case 4713 : return "+proj=longlat +ellps=clrk80 +towgs84=-79,-129,145,0,0,0,0";
+ case 4714 : return "+proj=longlat +ellps=intl +towgs84=-127,-769,472,0,0,0,0";
+ case 4715 : return "+proj=longlat +ellps=intl +towgs84=-104,-129,239,0,0,0,0";
+ case 4716 : return "+proj=longlat +ellps=intl +towgs84=298,-304,-375,0,0,0,0";
+ case 4717 : return "+proj=longlat +ellps=clrk66 +towgs84=-2,151,181,0,0,0,0";
+ case 4718 : return "+proj=longlat +ellps=intl";
+ case 4719 : return "+proj=longlat +ellps=intl +towgs84=211,147,111,0,0,0,0";
+ case 4720 : return "+proj=longlat +ellps=WGS72";
+ case 4721 : return "+proj=longlat +ellps=intl +towgs84=265.025,384.929,-194.046,0,0,0,0";
+ case 4722 : return "+proj=longlat +ellps=intl +towgs84=-794,119,-298,0,0,0,0";
+ case 4723 : return "+proj=longlat +ellps=clrk66 +towgs84=67.8,106.1,138.8,0,0,0,0";
+ case 4724 : return "+proj=longlat +ellps=intl +towgs84=208,-435,-229,0,0,0,0";
+ case 4725 : return "+proj=longlat +ellps=intl +towgs84=189,-79,-202,0,0,0,0";
+ case 4726 : return "+proj=longlat +ellps=clrk66";
+ case 4727 : return "+proj=longlat +ellps=intl";
+ case 4728 : return "+proj=longlat +ellps=intl +towgs84=-307,-92,127,0,0,0,0";
+ case 4729 : return "+proj=longlat +ellps=intl +towgs84=185,165,42,0,0,0,0";
+ case 4730 : return "+proj=longlat +ellps=intl +towgs84=170,42,84,0,0,0,0";
+ case 4731 : return "+proj=longlat +ellps=clrk80 +towgs84=51,391,-36,0,0,0,0";
+ case 4732 : return "+proj=longlat +a=6378270 +b=6356794.343434343 +towgs84=102,52,-38,0,0,0,0";
+ case 4733 : return "+proj=longlat +ellps=intl +towgs84=276,-57,149,0,0,0,0";
+ case 4734 : return "+proj=longlat +ellps=intl +towgs84=-632,438,-609,0,0,0,0";
+ case 4735 : return "+proj=longlat +ellps=intl +towgs84=647,1777,-1124,0,0,0,0";
+ case 4736 : return "+proj=longlat +ellps=clrk80 +towgs84=260,12,-147,0,0,0,0";
+ case 4737 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4738 : return "+proj=longlat +a=6378293.645208759 +b=6356617.987679838";
+ case 4739 : return "+proj=longlat +ellps=intl +towgs84=-156,-271,-189,0,0,0,0";
+ case 4740 : return "+proj=longlat +a=6378136 +b=6356751.361745712 +towgs84=0,0,1.5,-0,-0,0.076,0";
+ case 4741 : return "+proj=longlat +ellps=intl";
+ case 4742 : return "+proj=longlat +ellps=GRS80";
+ case 4743 : return "+proj=longlat +ellps=clrk80 +towgs84=84.1,-320.1,218.7,0,0,0,0";
+ case 4744 : return "+proj=longlat +ellps=clrk80";
+ case 4745 : return "+proj=longlat +ellps=bessel";
+ case 4746 : return "+proj=longlat +ellps=bessel";
+ case 4747 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4748 : return "+proj=longlat +a=6378306.3696 +b=6356571.996 +towgs84=51,391,-36,0,0,0,0";
+ case 4749 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4750 : return "+proj=longlat +ellps=WGS84 +towgs84=-56.263,16.136,-22.856,0,0,0,0";
+ case 4751 : return "+proj=longlat +a=6377295.664 +b=6356094.667915204";
+ case 4752 : return "+proj=longlat +a=6378306.3696 +b=6356571.996 +towgs84=51,391,-36,0,0,0,0";
+ case 4753 : return "+proj=longlat +ellps=intl";
+ case 4754 : return "+proj=longlat +ellps=intl +towgs84=-208.406,-109.878,-2.5764,0,0,0,0";
+ case 4755 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0";
+ case 4756 : return "+proj=longlat +ellps=WGS84";
+ case 4757 : return "+proj=longlat +ellps=WGS84";
+ case 4758 : return "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0";
+ case 4759 : return "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0";
+ case 4760 : return "+proj=longlat +ellps=WGS66";
+ case 4801 : return "+proj=longlat +ellps=bessel +pm=bern";
+ case 4802 : return "+proj=longlat +ellps=intl +pm=bogota";
+ case 4803 : return "+proj=longlat +ellps=intl +pm=lisbon";
+ case 4804 : return "+proj=longlat +ellps=bessel +towgs84=-587.8,519.75,145.76,0,0,0,0 +pm=jakarta";
+ case 4805 : return "+proj=longlat +ellps=bessel +pm=ferro";
+ case 4806 : return "+proj=longlat +ellps=intl +pm=rome";
+ case 4807 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris";
+ case 4808 : return "+proj=longlat +ellps=bessel +pm=jakarta";
+ case 4809 : return "+proj=longlat +ellps=intl +pm=brussels";
+ case 4810 : return "+proj=longlat +ellps=intl +towgs84=-189,-242,-91,0,0,0,0 +pm=paris";
+ case 4811 : return "+proj=longlat +a=6378249.2 +b=6356515 +towgs84=-73,-247,227,0,0,0,0 +pm=paris";
+ case 4813 : return "+proj=longlat +ellps=bessel +pm=jakarta";
+ case 4814 : return "+proj=longlat +ellps=bessel +pm=stockholm";
+ case 4815 : return "+proj=longlat +ellps=bessel +pm=athens";
+ case 4816 : return "+proj=longlat +a=6378249.2 +b=6356515 +pm=paris";
+ case 4817 : return "+proj=longlat +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo";
+ case 4818 : return "+proj=longlat +ellps=bessel +pm=ferro";
+ case 4819 : return "+proj=longlat +ellps=clrk80 +pm=paris";
+ case 4820 : return "+proj=longlat +ellps=bessel +pm=jakarta";
+ case 4821 : return "+proj=longlat +a=6378249.2 +b=6356515 +pm=paris";
+ case 4901 : return "+proj=longlat +a=6376523 +b=6355862.933255573 +pm=paris";
+ case 4902 : return "+proj=longlat +a=6376523 +b=6355862.933255573 +pm=paris";
+ case 4903 : return "+proj=longlat +a=6378298.3 +b=6356657.142669561 +pm=madrid";
+ case 4904 : return "+proj=longlat +ellps=bessel +pm=lisbon";
+ case 20004 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=4500000 +y_0=0 +ellps=krass +units=m";
+ case 20005 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=5500000 +y_0=0 +ellps=krass +units=m";
+ case 20006 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=6500000 +y_0=0 +ellps=krass +units=m";
+ case 20007 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=7500000 +y_0=0 +ellps=krass +units=m";
+ case 20008 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=8500000 +y_0=0 +ellps=krass +units=m";
+ case 20009 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=9500000 +y_0=0 +ellps=krass +units=m";
+ case 20010 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=10500000 +y_0=0 +ellps=krass +units=m";
+ case 20011 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=11500000 +y_0=0 +ellps=krass +units=m";
+ case 20012 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=12500000 +y_0=0 +ellps=krass +units=m";
+ case 20013 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=13500000 +y_0=0 +ellps=krass +units=m";
+ case 20014 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=14500000 +y_0=0 +ellps=krass +units=m";
+ case 20015 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=15500000 +y_0=0 +ellps=krass +units=m";
+ case 20016 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=16500000 +y_0=0 +ellps=krass +units=m";
+ case 20017 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=17500000 +y_0=0 +ellps=krass +units=m";
+ case 20018 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=18500000 +y_0=0 +ellps=krass +units=m";
+ case 20019 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=19500000 +y_0=0 +ellps=krass +units=m";
+ case 20020 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=20500000 +y_0=0 +ellps=krass +units=m";
+ case 20021 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=21500000 +y_0=0 +ellps=krass +units=m";
+ case 20022 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=22500000 +y_0=0 +ellps=krass +units=m";
+ case 20023 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=23500000 +y_0=0 +ellps=krass +units=m";
+ case 20024 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=24500000 +y_0=0 +ellps=krass +units=m";
+ case 20025 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=25500000 +y_0=0 +ellps=krass +units=m";
+ case 20026 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=26500000 +y_0=0 +ellps=krass +units=m";
+ case 20027 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=27500000 +y_0=0 +ellps=krass +units=m";
+ case 20028 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=28500000 +y_0=0 +ellps=krass +units=m";
+ case 20029 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=29500000 +y_0=0 +ellps=krass +units=m";
+ case 20030 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=30500000 +y_0=0 +ellps=krass +units=m";
+ case 20031 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=31500000 +y_0=0 +ellps=krass +units=m";
+ case 20032 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=32500000 +y_0=0 +ellps=krass +units=m";
+ case 20064 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20065 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20066 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20067 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20068 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20069 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20070 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20071 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20072 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20073 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20074 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20075 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20076 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20077 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20078 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20079 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20080 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20081 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20082 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20083 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20084 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20085 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20086 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20087 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20088 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20089 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20090 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20091 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20092 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 20135 : return "+proj=utm +zone=35 +ellps=clrk80 +units=m";
+ case 20136 : return "+proj=utm +zone=36 +ellps=clrk80 +units=m";
+ case 20137 : return "+proj=utm +zone=37 +ellps=clrk80 +units=m";
+ case 20138 : return "+proj=utm +zone=38 +ellps=clrk80 +units=m";
+ case 20248 : return "+proj=utm +zone=48 +south +ellps=aust_SA +units=m";
+ case 20249 : return "+proj=utm +zone=49 +south +ellps=aust_SA +units=m";
+ case 20250 : return "+proj=utm +zone=50 +south +ellps=aust_SA +units=m";
+ case 20251 : return "+proj=utm +zone=51 +south +ellps=aust_SA +units=m";
+ case 20252 : return "+proj=utm +zone=52 +south +ellps=aust_SA +units=m";
+ case 20253 : return "+proj=utm +zone=53 +south +ellps=aust_SA +units=m";
+ case 20254 : return "+proj=utm +zone=54 +south +ellps=aust_SA +units=m";
+ case 20255 : return "+proj=utm +zone=55 +south +ellps=aust_SA +units=m";
+ case 20256 : return "+proj=utm +zone=56 +south +ellps=aust_SA +units=m";
+ case 20257 : return "+proj=utm +zone=57 +south +ellps=aust_SA +units=m";
+ case 20258 : return "+proj=utm +zone=58 +south +ellps=aust_SA +units=m";
+ case 20348 : return "+proj=utm +zone=48 +south +ellps=aust_SA +units=m";
+ case 20349 : return "+proj=utm +zone=49 +south +ellps=aust_SA +units=m";
+ case 20350 : return "+proj=utm +zone=50 +south +ellps=aust_SA +units=m";
+ case 20351 : return "+proj=utm +zone=51 +south +ellps=aust_SA +units=m";
+ case 20352 : return "+proj=utm +zone=52 +south +ellps=aust_SA +units=m";
+ case 20353 : return "+proj=utm +zone=53 +south +ellps=aust_SA +units=m";
+ case 20354 : return "+proj=utm +zone=54 +south +ellps=aust_SA +units=m";
+ case 20355 : return "+proj=utm +zone=55 +south +ellps=aust_SA +units=m";
+ case 20356 : return "+proj=utm +zone=56 +south +ellps=aust_SA +units=m";
+ case 20357 : return "+proj=utm +zone=57 +south +ellps=aust_SA +units=m";
+ case 20358 : return "+proj=utm +zone=58 +south +ellps=aust_SA +units=m";
+ case 20436 : return "+proj=utm +zone=36 +ellps=intl +units=m";
+ case 20437 : return "+proj=utm +zone=37 +ellps=intl +units=m";
+ case 20438 : return "+proj=utm +zone=38 +ellps=intl +units=m";
+ case 20439 : return "+proj=utm +zone=39 +ellps=intl +units=m";
+ case 20440 : return "+proj=utm +zone=40 +ellps=intl +units=m";
+ case 20499 : return "+proj=utm +zone=39 +ellps=intl +units=m";
+ case 20538 : return "+proj=utm +zone=38 +ellps=krass +towgs84=-43,-163,45,0,0,0,0 +units=m";
+ case 20539 : return "+proj=utm +zone=39 +ellps=krass +towgs84=-43,-163,45,0,0,0,0 +units=m";
+ case 20790 : return "+proj=tmerc +lat_0=39.66666666666666 +lon_0=1 +k=1 +x_0=200000 +y_0=300000 +ellps=intl +pm=lisbon +units=m";
+ case 20791 : return "+proj=tmerc +lat_0=39.66666666666666 +lon_0=1 +k=1 +x_0=0 +y_0=0 +ellps=intl +pm=lisbon +units=m";
+ case 20822 : return "+proj=utm +zone=22 +south +ellps=intl +units=m";
+ case 20823 : return "+proj=utm +zone=23 +south +ellps=intl +units=m";
+ case 20824 : return "+proj=utm +zone=24 +south +ellps=intl +units=m";
+ case 20934 : return "+proj=utm +zone=34 +south +a=6378249.145 +b=6356514.966398753 +units=m";
+ case 20935 : return "+proj=utm +zone=35 +south +a=6378249.145 +b=6356514.966398753 +units=m";
+ case 20936 : return "+proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +units=m";
+ case 21035 : return "+proj=utm +zone=35 +south +ellps=clrk80 +units=m";
+ case 21036 : return "+proj=utm +zone=36 +south +ellps=clrk80 +units=m";
+ case 21037 : return "+proj=utm +zone=37 +south +ellps=clrk80 +units=m";
+ case 21095 : return "+proj=utm +zone=35 +ellps=clrk80 +units=m";
+ case 21096 : return "+proj=utm +zone=36 +ellps=clrk80 +units=m";
+ case 21097 : return "+proj=utm +zone=37 +ellps=clrk80 +units=m";
+ case 21100 : return "+proj=merc +lon_0=110 +k=0.997 +x_0=3900000 +y_0=900000 +ellps=bessel +pm=jakarta +units=m";
+ case 21148 : return "+proj=utm +zone=48 +south +ellps=bessel +units=m";
+ case 21149 : return "+proj=utm +zone=49 +south +ellps=bessel +units=m";
+ case 21150 : return "+proj=utm +zone=50 +south +ellps=bessel +units=m";
+ case 21291 : return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +towgs84=31.95,300.99,419.19,0,0,0,0 +units=m";
+ case 21292 : return "+proj=tmerc +lat_0=13.17638888888889 +lon_0=-59.55972222222222 +k=0.9999986 +x_0=30000 +y_0=75000 +ellps=clrk80 +towgs84=31.95,300.99,419.19,0,0,0,0 +units=m";
+ case 21413 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=13500000 +y_0=0 +ellps=krass +units=m";
+ case 21414 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=14500000 +y_0=0 +ellps=krass +units=m";
+ case 21415 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=15500000 +y_0=0 +ellps=krass +units=m";
+ case 21416 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=16500000 +y_0=0 +ellps=krass +units=m";
+ case 21417 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=17500000 +y_0=0 +ellps=krass +units=m";
+ case 21418 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=18500000 +y_0=0 +ellps=krass +units=m";
+ case 21419 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=19500000 +y_0=0 +ellps=krass +units=m";
+ case 21420 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=20500000 +y_0=0 +ellps=krass +units=m";
+ case 21421 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=21500000 +y_0=0 +ellps=krass +units=m";
+ case 21422 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=22500000 +y_0=0 +ellps=krass +units=m";
+ case 21423 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=23500000 +y_0=0 +ellps=krass +units=m";
+ case 21453 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21454 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21455 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21456 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21457 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21458 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21459 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21460 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21461 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21462 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21463 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21473 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21474 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21475 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21476 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21477 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21478 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21479 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21480 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21481 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21482 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21483 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 21500 : return "+proj=lcc +lat_1=49.83333333333334 +lat_2=51.16666666666666 +lat_0=90 +lon_0=0 +x_0=150000 +y_0=5400000 +ellps=intl +pm=brussels +units=m";
+ case 21780 : return "+proj=somerc +lat_0=46.95240555555556 +lon_0=0 +x_0=0 +y_0=0 +ellps=bessel +pm=bern +units=m";
+ case 21781 : return "+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +x_0=600000 +y_0=200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m";
+ case 21817 : return "+proj=utm +zone=17 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21818 : return "+proj=utm +zone=18 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21891 : return "+proj=tmerc +lat_0=4.599047222222222 +lon_0=-77.08091666666667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21892 : return "+proj=tmerc +lat_0=4.599047222222222 +lon_0=-74.08091666666667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21893 : return "+proj=tmerc +lat_0=4.599047222222222 +lon_0=-71.08091666666667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21894 : return "+proj=tmerc +lat_0=4.599047222222222 +lon_0=-68.08091666666667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21896 : return "+proj=tmerc +lat_0=4.599047222222222 +lon_0=-77.08091666666667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21897 : return "+proj=tmerc +lat_0=4.599047222222222 +lon_0=-74.08091666666667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21898 : return "+proj=tmerc +lat_0=4.599047222222222 +lon_0=-71.08091666666667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 21899 : return "+proj=tmerc +lat_0=4.599047222222222 +lon_0=-68.08091666666667 +k=1 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m";
+ case 22032 : return "+proj=utm +zone=32 +south +ellps=clrk80 +units=m";
+ case 22033 : return "+proj=utm +zone=33 +south +ellps=clrk80 +units=m";
+ case 22091 : return "+proj=tmerc +lat_0=0 +lon_0=11.5 +k=0.9996 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 22092 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=0.9996 +x_0=500000 +y_0=10000000 +ellps=clrk80 +units=m";
+ case 22171 : return "+proj=tmerc +lat_0=-90 +lon_0=-72 +k=1 +x_0=1500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22172 : return "+proj=tmerc +lat_0=-90 +lon_0=-69 +k=1 +x_0=2500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22173 : return "+proj=tmerc +lat_0=-90 +lon_0=-66 +k=1 +x_0=3500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22174 : return "+proj=tmerc +lat_0=-90 +lon_0=-63 +k=1 +x_0=4500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22175 : return "+proj=tmerc +lat_0=-90 +lon_0=-60 +k=1 +x_0=5500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22176 : return "+proj=tmerc +lat_0=-90 +lon_0=-57 +k=1 +x_0=6500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22177 : return "+proj=tmerc +lat_0=-90 +lon_0=-54 +k=1 +x_0=7500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22181 : return "+proj=tmerc +lat_0=-90 +lon_0=-72 +k=1 +x_0=1500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22182 : return "+proj=tmerc +lat_0=-90 +lon_0=-69 +k=1 +x_0=2500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22183 : return "+proj=tmerc +lat_0=-90 +lon_0=-66 +k=1 +x_0=3500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22184 : return "+proj=tmerc +lat_0=-90 +lon_0=-63 +k=1 +x_0=4500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22185 : return "+proj=tmerc +lat_0=-90 +lon_0=-60 +k=1 +x_0=5500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22186 : return "+proj=tmerc +lat_0=-90 +lon_0=-57 +k=1 +x_0=6500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22187 : return "+proj=tmerc +lat_0=-90 +lon_0=-54 +k=1 +x_0=7500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 22191 : return "+proj=tmerc +lat_0=-90 +lon_0=-72 +k=1 +x_0=1500000 +y_0=0 +ellps=intl +units=m";
+ case 22192 : return "+proj=tmerc +lat_0=-90 +lon_0=-69 +k=1 +x_0=2500000 +y_0=0 +ellps=intl +units=m";
+ case 22193 : return "+proj=tmerc +lat_0=-90 +lon_0=-66 +k=1 +x_0=3500000 +y_0=0 +ellps=intl +units=m";
+ case 22194 : return "+proj=tmerc +lat_0=-90 +lon_0=-63 +k=1 +x_0=4500000 +y_0=0 +ellps=intl +units=m";
+ case 22195 : return "+proj=tmerc +lat_0=-90 +lon_0=-60 +k=1 +x_0=5500000 +y_0=0 +ellps=intl +units=m";
+ case 22196 : return "+proj=tmerc +lat_0=-90 +lon_0=-57 +k=1 +x_0=6500000 +y_0=0 +ellps=intl +units=m";
+ case 22197 : return "+proj=tmerc +lat_0=-90 +lon_0=-54 +k=1 +x_0=7500000 +y_0=0 +ellps=intl +units=m";
+ case 22234 : return "+proj=utm +zone=34 +south +a=6378249.145 +b=6356514.966398753 +units=m";
+ case 22235 : return "+proj=utm +zone=35 +south +a=6378249.145 +b=6356514.966398753 +units=m";
+ case 22236 : return "+proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +units=m";
+ case 22332 : return "+proj=utm +zone=32 +a=6378249.2 +b=6356515 +units=m";
+ case 22391 : return "+proj=lcc +lat_1=36 +lat_0=36 +lon_0=9.9 +k_0=0.999625544 +x_0=500000 +y_0=300000 +a=6378249.2 +b=6356515 +units=m";
+ case 22392 : return "+proj=lcc +lat_1=33.3 +lat_0=33.3 +lon_0=9.9 +k_0=0.999625769 +x_0=500000 +y_0=300000 +a=6378249.2 +b=6356515 +units=m";
+ case 22521 : return "+proj=utm +zone=21 +south +ellps=intl +towgs84=-206,172,-6,0,0,0,0 +units=m";
+ case 22522 : return "+proj=utm +zone=22 +south +ellps=intl +towgs84=-206,172,-6,0,0,0,0 +units=m";
+ case 22523 : return "+proj=utm +zone=23 +south +ellps=intl +towgs84=-206,172,-6,0,0,0,0 +units=m";
+ case 22524 : return "+proj=utm +zone=24 +south +ellps=intl +towgs84=-206,172,-6,0,0,0,0 +units=m";
+ case 22525 : return "+proj=utm +zone=25 +south +ellps=intl +towgs84=-206,172,-6,0,0,0,0 +units=m";
+ case 22700 : return "+proj=lcc +lat_1=34.65 +lat_0=34.65 +lon_0=37.35 +k_0=0.9996256 +x_0=300000 +y_0=300000 +a=6378249.2 +b=6356515 +units=m";
+ case 22770 : return "+proj=lcc +lat_1=34.65 +lat_0=34.65 +lon_0=37.35 +k_0=0.9996256 +x_0=300000 +y_0=300000 +a=6378249.2 +b=6356515 +units=m";
+ case 22780 : return "+proj=sterea +lat_0=34.2 +lon_0=39.15 +k=0.9995341 +x_0=0 +y_0=0 +a=6378249.2 +b=6356515 +units=m";
+ case 22832 : return "+proj=utm +zone=32 +a=6378249.2 +b=6356515 +units=m";
+ case 22991 : return "+proj=tmerc +lat_0=30 +lon_0=35 +k=1 +x_0=300000 +y_0=1100000 +ellps=helmert +units=m";
+ case 22992 : return "+proj=tmerc +lat_0=30 +lon_0=31 +k=1 +x_0=615000 +y_0=810000 +ellps=helmert +units=m";
+ case 22993 : return "+proj=tmerc +lat_0=30 +lon_0=27 +k=1 +x_0=700000 +y_0=200000 +ellps=helmert +units=m";
+ case 22994 : return "+proj=tmerc +lat_0=30 +lon_0=27 +k=1 +x_0=700000 +y_0=1200000 +ellps=helmert +units=m";
+ case 23028 : return "+proj=utm +zone=28 +ellps=intl +units=m";
+ case 23029 : return "+proj=utm +zone=29 +ellps=intl +units=m";
+ case 23030 : return "+proj=utm +zone=30 +ellps=intl +units=m";
+ case 23031 : return "+proj=utm +zone=31 +ellps=intl +units=m";
+ case 23032 : return "+proj=utm +zone=32 +ellps=intl +units=m";
+ case 23033 : return "+proj=utm +zone=33 +ellps=intl +units=m";
+ case 23034 : return "+proj=utm +zone=34 +ellps=intl +units=m";
+ case 23035 : return "+proj=utm +zone=35 +ellps=intl +units=m";
+ case 23036 : return "+proj=utm +zone=36 +ellps=intl +units=m";
+ case 23037 : return "+proj=utm +zone=37 +ellps=intl +units=m";
+ case 23038 : return "+proj=utm +zone=38 +ellps=intl +units=m";
+ case 23090 : return "+proj=tmerc +lat_0=0 +lon_0=0 +k=0.9996 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 23095 : return "+proj=tmerc +lat_0=0 +lon_0=5 +k=0.9996 +x_0=500000 +y_0=0 +ellps=intl +units=m";
+ case 23239 : return "+proj=utm +zone=39 +ellps=clrk80 +units=m";
+ case 23240 : return "+proj=utm +zone=40 +ellps=clrk80 +units=m";
+ case 23433 : return "+proj=utm +zone=33 +a=6378249.2 +b=6356515 +units=m";
+ case 23700 : return "+proj=somerc +lat_0=47.14439372222222 +lon_0=19.04857177777778 +x_0=650000 +y_0=200000 +ellps=GRS67 +units=m";
+ case 23830 : return "+proj=tmerc +lat_0=0 +lon_0=94.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23831 : return "+proj=tmerc +lat_0=0 +lon_0=97.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23832 : return "+proj=tmerc +lat_0=0 +lon_0=100.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23833 : return "+proj=tmerc +lat_0=0 +lon_0=103.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23834 : return "+proj=tmerc +lat_0=0 +lon_0=106.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23835 : return "+proj=tmerc +lat_0=0 +lon_0=109.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23836 : return "+proj=tmerc +lat_0=0 +lon_0=112.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23837 : return "+proj=tmerc +lat_0=0 +lon_0=115.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23838 : return "+proj=tmerc +lat_0=0 +lon_0=118.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23839 : return "+proj=tmerc +lat_0=0 +lon_0=121.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23840 : return "+proj=tmerc +lat_0=0 +lon_0=124.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23841 : return "+proj=tmerc +lat_0=0 +lon_0=127.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23842 : return "+proj=tmerc +lat_0=0 +lon_0=130.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23843 : return "+proj=tmerc +lat_0=0 +lon_0=133.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23844 : return "+proj=tmerc +lat_0=0 +lon_0=136.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23845 : return "+proj=tmerc +lat_0=0 +lon_0=139.5 +k=0.9999 +x_0=200000 +y_0=1500000 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23846 : return "+proj=utm +zone=46 +a=6378160 +b=6356774.50408554 +units=m";
+ case 23847 : return "+proj=utm +zone=47 +a=6378160 +b=6356774.50408554 +units=m";
+ case 23848 : return "+proj=utm +zone=48 +a=6378160 +b=6356774.50408554 +units=m";
+ case 23849 : return "+proj=utm +zone=49 +a=6378160 +b=6356774.50408554 +units=m";
+ case 23850 : return "+proj=utm +zone=50 +a=6378160 +b=6356774.50408554 +units=m";
+ case 23851 : return "+proj=utm +zone=51 +a=6378160 +b=6356774.50408554 +units=m";
+ case 23852 : return "+proj=utm +zone=52 +a=6378160 +b=6356774.50408554 +units=m";
+ case 23853 : return "+proj=utm +zone=53 +a=6378160 +b=6356774.50408554 +units=m";
+ case 23866 : return "+proj=utm +zone=46 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23867 : return "+proj=utm +zone=47 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23868 : return "+proj=utm +zone=48 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23869 : return "+proj=utm +zone=49 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23870 : return "+proj=utm +zone=50 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23871 : return "+proj=utm +zone=51 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23872 : return "+proj=utm +zone=52 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23877 : return "+proj=utm +zone=47 +south +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23878 : return "+proj=utm +zone=48 +south +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23879 : return "+proj=utm +zone=49 +south +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23880 : return "+proj=utm +zone=50 +south +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23881 : return "+proj=utm +zone=51 +south +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23882 : return "+proj=utm +zone=52 +south +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23883 : return "+proj=utm +zone=53 +south +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23884 : return "+proj=utm +zone=54 +south +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 23886 : return "+proj=utm +zone=46 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23887 : return "+proj=utm +zone=47 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23888 : return "+proj=utm +zone=48 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23889 : return "+proj=utm +zone=49 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23890 : return "+proj=utm +zone=50 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23891 : return "+proj=utm +zone=51 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23892 : return "+proj=utm +zone=52 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23893 : return "+proj=utm +zone=53 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23894 : return "+proj=utm +zone=54 +south +a=6378160 +b=6356774.50408554 +units=m";
+ case 23946 : return "+proj=utm +zone=46 +a=6377276.345 +b=6356075.41314024 +towgs84=217,823,299,0,0,0,0 +units=m";
+ case 23947 : return "+proj=utm +zone=47 +a=6377276.345 +b=6356075.41314024 +towgs84=217,823,299,0,0,0,0 +units=m";
+ case 23948 : return "+proj=utm +zone=48 +a=6377276.345 +b=6356075.41314024 +towgs84=217,823,299,0,0,0,0 +units=m";
+ case 24047 : return "+proj=utm +zone=47 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 24048 : return "+proj=utm +zone=48 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 24100 : return "+proj=lcc +lat_1=18 +lat_0=18 +lon_0=-77 +k_0=1 +x_0=167638.49597 +y_0=121918.90616 +ellps=clrk80 +to_meter=0.3047972654";
+ case 24200 : return "+proj=lcc +lat_1=18 +lat_0=18 +lon_0=-77 +k_0=1 +x_0=250000 +y_0=150000 +ellps=clrk66 +units=m";
+ case 24305 : return "+proj=utm +zone=45 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 24306 : return "+proj=utm +zone=46 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 24311 : return "+proj=utm +zone=41 +a=6377301.243 +b=6356100.230165384 +units=m";
+ case 24312 : return "+proj=utm +zone=42 +a=6377301.243 +b=6356100.230165384 +units=m";
+ case 24313 : return "+proj=utm +zone=43 +a=6377301.243 +b=6356100.230165384 +units=m";
+ case 24342 : return "+proj=utm +zone=42 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24343 : return "+proj=utm +zone=43 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24344 : return "+proj=utm +zone=44 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24345 : return "+proj=utm +zone=45 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24346 : return "+proj=utm +zone=46 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24347 : return "+proj=utm +zone=47 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24370 : return "+proj=lcc +lat_1=39.5 +lat_0=39.5 +lon_0=68 +k_0=0.99846154 +x_0=2153865.73916853 +y_0=2368292.194628102 +a=6377299.36559538 +b=6356098.357204818 +to_meter=0.9143985307444408";
+ case 24371 : return "+proj=lcc +lat_1=32.5 +lat_0=32.5 +lon_0=68 +k_0=0.99878641 +x_0=2743195.592233322 +y_0=914398.5307444407 +a=6377299.36559538 +b=6356098.357204818 +to_meter=0.9143985307444408";
+ case 24372 : return "+proj=lcc +lat_1=26 +lat_0=26 +lon_0=74 +k_0=0.99878641 +x_0=2743195.592233322 +y_0=914398.5307444407 +a=6377299.36559538 +b=6356098.357204818 +to_meter=0.9143985307444408";
+ case 24373 : return "+proj=lcc +lat_1=19 +lat_0=19 +lon_0=80 +k_0=0.99878641 +x_0=2743195.592233322 +y_0=914398.5307444407 +a=6377299.36559538 +b=6356098.357204818 +to_meter=0.9143985307444408";
+ case 24374 : return "+proj=lcc +lat_1=12 +lat_0=12 +lon_0=80 +k_0=0.99878641 +x_0=2743195.592233322 +y_0=914398.5307444407 +a=6377299.36559538 +b=6356098.357204818 +to_meter=0.9143985307444408";
+ case 24375 : return "+proj=lcc +lat_1=26 +lat_0=26 +lon_0=90 +k_0=0.99878641 +x_0=2743185.69 +y_0=914395.23 +a=6377276.345 +b=6356075.41314024 +units=m";
+ case 24376 : return "+proj=lcc +lat_1=32.5 +lat_0=32.5 +lon_0=68 +k_0=0.99878641 +x_0=2743196.4 +y_0=914398.8 +a=6377301.243 +b=6356100.230165384 +units=m";
+ case 24377 : return "+proj=lcc +lat_1=26 +lat_0=26 +lon_0=74 +k_0=0.99878641 +x_0=2743196.4 +y_0=914398.8 +a=6377301.243 +b=6356100.230165384 +units=m";
+ case 24378 : return "+proj=lcc +lat_1=32.5 +lat_0=32.5 +lon_0=68 +k_0=0.99878641 +x_0=2743195.5 +y_0=914398.5 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24379 : return "+proj=lcc +lat_1=26 +lat_0=26 +lon_0=74 +k_0=0.99878641 +x_0=2743195.5 +y_0=914398.5 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24380 : return "+proj=lcc +lat_1=26 +lat_0=26 +lon_0=90 +k_0=0.99878641 +x_0=2743195.5 +y_0=914398.5 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24381 : return "+proj=lcc +lat_1=19 +lat_0=19 +lon_0=80 +k_0=0.99878641 +x_0=2743195.5 +y_0=914398.5 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24382 : return "+proj=lcc +lat_1=26 +lat_0=26 +lon_0=90 +k_0=0.99878641 +x_0=2743195.592233322 +y_0=914398.5307444407 +a=6377299.36559538 +b=6356098.357204818 +to_meter=0.9143985307444408";
+ case 24383 : return "+proj=lcc +lat_1=12 +lat_0=12 +lon_0=80 +k_0=0.99878641 +x_0=2743195.5 +y_0=914398.5 +a=6377299.151 +b=6356098.145120132 +towgs84=295,736,257,0,0,0,0 +units=m";
+ case 24500 : return "+proj=cass +lat_0=1.287646666666667 +lon_0=103.8530022222222 +x_0=30000 +y_0=30000 +a=6377304.063 +b=6356103.038993155 +towgs84=-11,851,5,0,0,0,0 +units=m";
+ case 24547 : return "+proj=utm +zone=47 +a=6377304.063 +b=6356103.038993155 +towgs84=-11,851,5,0,0,0,0 +units=m";
+ case 24548 : return "+proj=utm +zone=48 +a=6377304.063 +b=6356103.038993155 +towgs84=-11,851,5,0,0,0,0 +units=m";
+ case 24571 : return "+proj=omerc +lat_0=4 +lonc=102.25 +alpha=323.0257905 +k=0.99984 +x_0=804671.2997750348 +y_0=0 +a=6377304.063 +b=6356103.038993155 +towgs84=-11,851,5,0,0,0,0 +to_meter=20.11678249437587";
+ case 24600 : return "+proj=lcc +lat_1=32.5 +lat_0=32.5 +lon_0=45 +k_0=0.9987864078000001 +x_0=1500000 +y_0=1166200 +ellps=clrk80 +towgs84=-294.7,-200.1,525.5,0,0,0,0 +units=m";
+ case 24718 : return "+proj=utm +zone=18 +ellps=intl +towgs84=-273.5,110.6,-357.9,0,0,0,0 +units=m";
+ case 24719 : return "+proj=utm +zone=19 +ellps=intl +towgs84=-273.5,110.6,-357.9,0,0,0,0 +units=m";
+ case 24720 : return "+proj=utm +zone=20 +ellps=intl +towgs84=-273.5,110.6,-357.9,0,0,0,0 +units=m";
+ case 24817 : return "+proj=utm +zone=17 +ellps=intl +units=m";
+ case 24818 : return "+proj=utm +zone=18 +ellps=intl +units=m";
+ case 24819 : return "+proj=utm +zone=19 +ellps=intl +units=m";
+ case 24820 : return "+proj=utm +zone=20 +ellps=intl +units=m";
+ case 24821 : return "+proj=utm +zone=21 +ellps=intl +units=m";
+ case 24877 : return "+proj=utm +zone=17 +south +ellps=intl +units=m";
+ case 24878 : return "+proj=utm +zone=18 +south +ellps=intl +units=m";
+ case 24879 : return "+proj=utm +zone=19 +south +ellps=intl +units=m";
+ case 24880 : return "+proj=utm +zone=20 +south +ellps=intl +units=m";
+ case 24881 : return "+proj=utm +zone=21 +south +ellps=intl +units=m";
+ case 24882 : return "+proj=utm +zone=22 +south +ellps=intl +units=m";
+ case 24891 : return "+proj=tmerc +lat_0=-6 +lon_0=-80.5 +k=0.99983008 +x_0=222000 +y_0=1426834.743 +ellps=intl +units=m";
+ case 24892 : return "+proj=tmerc +lat_0=-9.5 +lon_0=-76 +k=0.99932994 +x_0=720000 +y_0=1039979.159 +ellps=intl +units=m";
+ case 24893 : return "+proj=tmerc +lat_0=-9.5 +lon_0=-70.5 +k=0.99952992 +x_0=1324000 +y_0=1040084.558 +ellps=intl +units=m";
+ case 25000 : return "+proj=tmerc +lat_0=4.666666666666667 +lon_0=-1 +k=0.99975 +x_0=274319.51 +y_0=0 +ellps=clrk80 +towgs84=-130,29,364,0,0,0,0 +units=m";
+ case 25231 : return "+proj=utm +zone=31 +a=6378249.2 +b=6356515 +units=m";
+ case 25391 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +units=m";
+ case 25392 : return "+proj=tmerc +lat_0=0 +lon_0=119 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +units=m";
+ case 25393 : return "+proj=tmerc +lat_0=0 +lon_0=121 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +units=m";
+ case 25394 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +units=m";
+ case 25395 : return "+proj=tmerc +lat_0=0 +lon_0=125 +k=0.99995 +x_0=500000 +y_0=0 +ellps=clrk66 +units=m";
+ case 25700 : return "+proj=merc +lon_0=110 +k=0.997 +x_0=3900000 +y_0=900000 +ellps=bessel +towgs84=-587.8,519.75,145.76,0,0,0,0 +pm=jakarta +units=m";
+ case 25828 : return "+proj=utm +zone=28 +ellps=GRS80 +units=m";
+ case 25829 : return "+proj=utm +zone=29 +ellps=GRS80 +units=m";
+ case 25830 : return "+proj=utm +zone=30 +ellps=GRS80 +units=m";
+ case 25831 : return "+proj=utm +zone=31 +ellps=GRS80 +units=m";
+ case 25832 : return "+proj=utm +zone=32 +ellps=GRS80 +units=m";
+ case 25833 : return "+proj=utm +zone=33 +ellps=GRS80 +units=m";
+ case 25834 : return "+proj=utm +zone=34 +ellps=GRS80 +units=m";
+ case 25835 : return "+proj=utm +zone=35 +ellps=GRS80 +units=m";
+ case 25836 : return "+proj=utm +zone=36 +ellps=GRS80 +units=m";
+ case 25837 : return "+proj=utm +zone=37 +ellps=GRS80 +units=m";
+ case 25838 : return "+proj=utm +zone=38 +ellps=GRS80 +units=m";
+ case 25884 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 25932 : return "+proj=utm +zone=32 +south +ellps=intl +units=m";
+ case 26191 : return "+proj=lcc +lat_1=33.3 +lat_0=33.3 +lon_0=-5.4 +k_0=0.999625769 +x_0=500000 +y_0=300000 +a=6378249.2 +b=6356515 +towgs84=31,146,47,0,0,0,0 +units=m";
+ case 26192 : return "+proj=lcc +lat_1=29.7 +lat_0=29.7 +lon_0=-5.4 +k_0=0.9996155960000001 +x_0=500000 +y_0=300000 +a=6378249.2 +b=6356515 +towgs84=31,146,47,0,0,0,0 +units=m";
+ case 26193 : return "+proj=lcc +lat_1=26.1 +lat_0=26.1 +lon_0=-5.4 +k_0=0.9996 +x_0=1200000 +y_0=400000 +a=6378249.2 +b=6356515 +towgs84=31,146,47,0,0,0,0 +units=m";
+ case 26194 : return "+proj=lcc +lat_1=26.1 +lat_0=26.1 +lon_0=-5.4 +k_0=0.999616304 +x_0=1200000 +y_0=400000 +a=6378249.2 +b=6356515 +towgs84=31,146,47,0,0,0,0 +units=m";
+ case 26195 : return "+proj=lcc +lat_1=22.5 +lat_0=22.5 +lon_0=-5.4 +k_0=0.999616437 +x_0=1500000 +y_0=400000 +a=6378249.2 +b=6356515 +towgs84=31,146,47,0,0,0,0 +units=m";
+ case 26237 : return "+proj=utm +zone=37 +ellps=bessel +towgs84=639,405,60,0,0,0,0 +units=m";
+ case 26331 : return "+proj=utm +zone=31 +ellps=clrk80 +units=m";
+ case 26332 : return "+proj=utm +zone=32 +ellps=clrk80 +units=m";
+ case 26391 : return "+proj=tmerc +lat_0=4 +lon_0=4.5 +k=0.99975 +x_0=230738.26 +y_0=0 +ellps=clrk80 +units=m";
+ case 26392 : return "+proj=tmerc +lat_0=4 +lon_0=8.5 +k=0.99975 +x_0=670553.98 +y_0=0 +ellps=clrk80 +units=m";
+ case 26393 : return "+proj=tmerc +lat_0=4 +lon_0=12.5 +k=0.99975 +x_0=1110369.7 +y_0=0 +ellps=clrk80 +units=m";
+ case 26432 : return "+proj=utm +zone=32 +south +ellps=intl +towgs84=-252.95,-4.11,-96.38,0,0,0,0 +units=m";
+ case 26591 : return "+proj=tmerc +lat_0=0 +lon_0=-3.45233333333333 +k=0.9996 +x_0=1500000 +y_0=0 +ellps=intl +pm=rome +units=m";
+ case 26592 : return "+proj=tmerc +lat_0=0 +lon_0=2.54766666666666 +k=0.9996 +x_0=2520000 +y_0=0 +ellps=intl +pm=rome +units=m";
+ case 26632 : return "+proj=utm +zone=32 +a=6378249.2 +b=6356515 +units=m";
+ case 26692 : return "+proj=utm +zone=32 +south +a=6378249.2 +b=6356515 +units=m";
+ case 26701 : return "+proj=utm +zone=1 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26702 : return "+proj=utm +zone=2 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26703 : return "+proj=utm +zone=3 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26704 : return "+proj=utm +zone=4 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26705 : return "+proj=utm +zone=5 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26706 : return "+proj=utm +zone=6 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26707 : return "+proj=utm +zone=7 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26708 : return "+proj=utm +zone=8 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26709 : return "+proj=utm +zone=9 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26710 : return "+proj=utm +zone=10 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26711 : return "+proj=utm +zone=11 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26712 : return "+proj=utm +zone=12 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26713 : return "+proj=utm +zone=13 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26714 : return "+proj=utm +zone=14 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26715 : return "+proj=utm +zone=15 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26716 : return "+proj=utm +zone=16 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26717 : return "+proj=utm +zone=17 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26718 : return "+proj=utm +zone=18 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26719 : return "+proj=utm +zone=19 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26720 : return "+proj=utm +zone=20 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26721 : return "+proj=utm +zone=21 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26722 : return "+proj=utm +zone=22 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 26729 : return "+proj=tmerc +lat_0=30.5 +lon_0=-85.83333333333333 +k=0.99996 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26730 : return "+proj=tmerc +lat_0=30 +lon_0=-87.5 +k=0.999933333 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26731 : return "+proj=omerc +lat_0=57 +lonc=-133.6666666666667 +alpha=323.1301023611111 +k=0.9999 +x_0=5000000.001016002 +y_0=-5000000.001016002 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26732 : return "+proj=tmerc +lat_0=54 +lon_0=-142 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26733 : return "+proj=tmerc +lat_0=54 +lon_0=-146 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26734 : return "+proj=tmerc +lat_0=54 +lon_0=-150 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26735 : return "+proj=tmerc +lat_0=54 +lon_0=-154 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26736 : return "+proj=tmerc +lat_0=54 +lon_0=-158 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26737 : return "+proj=tmerc +lat_0=54 +lon_0=-162 +k=0.9999 +x_0=213360.4267208534 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26738 : return "+proj=tmerc +lat_0=54 +lon_0=-166 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26739 : return "+proj=tmerc +lat_0=54 +lon_0=-170 +k=0.9999 +x_0=182880.3657607315 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26740 : return "+proj=lcc +lat_1=53.83333333333334 +lat_2=51.83333333333334 +lat_0=51 +lon_0=-176 +x_0=914401.8288036576 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26741 : return "+proj=lcc +lat_1=41.66666666666666 +lat_2=40 +lat_0=39.33333333333334 +lon_0=-122 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26742 : return "+proj=lcc +lat_1=39.83333333333334 +lat_2=38.33333333333334 +lat_0=37.66666666666666 +lon_0=-122 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26743 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.06666666666667 +lat_0=36.5 +lon_0=-120.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26744 : return "+proj=lcc +lat_1=37.25 +lat_2=36 +lat_0=35.33333333333334 +lon_0=-119 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26745 : return "+proj=lcc +lat_1=35.46666666666667 +lat_2=34.03333333333333 +lat_0=33.5 +lon_0=-118 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26746 : return "+proj=lcc +lat_1=33.88333333333333 +lat_2=32.78333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26747 : return "+proj=lcc +lat_1=34.41666666666666 +lat_2=33.86666666666667 +lat_0=34.13333333333333 +lon_0=-118.3333333333333 +x_0=1276106.450596901 +y_0=127079.524511049 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26748 : return "+proj=tmerc +lat_0=31 +lon_0=-110.1666666666667 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26749 : return "+proj=tmerc +lat_0=31 +lon_0=-111.9166666666667 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26750 : return "+proj=tmerc +lat_0=31 +lon_0=-113.75 +k=0.999933333 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26751 : return "+proj=lcc +lat_1=36.23333333333333 +lat_2=34.93333333333333 +lat_0=34.33333333333334 +lon_0=-92 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26752 : return "+proj=lcc +lat_1=34.76666666666667 +lat_2=33.3 +lat_0=32.66666666666666 +lon_0=-92 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26753 : return "+proj=lcc +lat_1=39.71666666666667 +lat_2=40.78333333333333 +lat_0=39.33333333333334 +lon_0=-105.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26754 : return "+proj=lcc +lat_1=39.75 +lat_2=38.45 +lat_0=37.83333333333334 +lon_0=-105.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26755 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.23333333333333 +lat_0=36.66666666666666 +lon_0=-105.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26756 : return "+proj=lcc +lat_1=41.86666666666667 +lat_2=41.2 +lat_0=40.83333333333334 +lon_0=-72.75 +x_0=182880.3657607315 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26757 : return "+proj=tmerc +lat_0=38 +lon_0=-75.41666666666667 +k=0.999995 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26758 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-81 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26759 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-82 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26760 : return "+proj=lcc +lat_1=30.75 +lat_2=29.58333333333333 +lat_0=29 +lon_0=-84.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26766 : return "+proj=tmerc +lat_0=30 +lon_0=-82.16666666666667 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26767 : return "+proj=tmerc +lat_0=30 +lon_0=-84.16666666666667 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26768 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-112.1666666666667 +k=0.9999473679999999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26769 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-114 +k=0.9999473679999999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26770 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-115.75 +k=0.999933333 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26771 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-88.33333333333333 +k=0.9999749999999999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26772 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-90.16666666666667 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26773 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26774 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26775 : return "+proj=lcc +lat_1=43.26666666666667 +lat_2=42.06666666666667 +lat_0=41.5 +lon_0=-93.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26776 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.61666666666667 +lat_0=40 +lon_0=-93.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26777 : return "+proj=lcc +lat_1=39.78333333333333 +lat_2=38.71666666666667 +lat_0=38.33333333333334 +lon_0=-98 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26778 : return "+proj=lcc +lat_1=38.56666666666667 +lat_2=37.26666666666667 +lat_0=36.66666666666666 +lon_0=-98.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26779 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=38.96666666666667 +lat_0=37.5 +lon_0=-84.25 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26780 : return "+proj=lcc +lat_1=36.73333333333333 +lat_2=37.93333333333333 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26781 : return "+proj=lcc +lat_1=31.16666666666667 +lat_2=32.66666666666666 +lat_0=30.66666666666667 +lon_0=-92.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26782 : return "+proj=lcc +lat_1=29.3 +lat_2=30.7 +lat_0=28.66666666666667 +lon_0=-91.33333333333333 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26783 : return "+proj=tmerc +lat_0=43.83333333333334 +lon_0=-68.5 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26784 : return "+proj=tmerc +lat_0=42.83333333333334 +lon_0=-70.16666666666667 +k=0.999966667 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26785 : return "+proj=lcc +lat_1=38.3 +lat_2=39.45 +lat_0=37.83333333333334 +lon_0=-77 +x_0=243840.4876809754 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26786 : return "+proj=lcc +lat_1=41.71666666666667 +lat_2=42.68333333333333 +lat_0=41 +lon_0=-71.5 +x_0=182880.3657607315 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26787 : return "+proj=lcc +lat_1=41.28333333333333 +lat_2=41.48333333333333 +lat_0=41 +lon_0=-70.5 +x_0=60960.12192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26791 : return "+proj=lcc +lat_1=47.03333333333333 +lat_2=48.63333333333333 +lat_0=46.5 +lon_0=-93.09999999999999 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26792 : return "+proj=lcc +lat_1=45.61666666666667 +lat_2=47.05 +lat_0=45 +lon_0=-94.25 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26793 : return "+proj=lcc +lat_1=43.78333333333333 +lat_2=45.21666666666667 +lat_0=43 +lon_0=-94 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26794 : return "+proj=tmerc +lat_0=29.66666666666667 +lon_0=-88.83333333333333 +k=0.99996 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26795 : return "+proj=tmerc +lat_0=30.5 +lon_0=-90.33333333333333 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26796 : return "+proj=tmerc +lat_0=35.83333333333334 +lon_0=-90.5 +k=0.999933333 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26797 : return "+proj=tmerc +lat_0=35.83333333333334 +lon_0=-92.5 +k=0.999933333 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26798 : return "+proj=tmerc +lat_0=36.16666666666666 +lon_0=-94.5 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26799 : return "+proj=lcc +lat_1=34.41666666666666 +lat_2=33.86666666666667 +lat_0=34.13333333333333 +lon_0=-118.3333333333333 +x_0=1276106.450596901 +y_0=1268253.006858014 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 26801 : return "+proj=tmerc +lat_0=41.5 +lon_0=-83.66666666666667 +k=0.999942857 +x_0=152400.3048006096 +y_0=0 +a=6378450.047548896 +b=6356826.621488444 +to_meter=0.3048006096012192";
+ case 26802 : return "+proj=tmerc +lat_0=41.5 +lon_0=-85.75 +k=0.999909091 +x_0=152400.3048006096 +y_0=0 +a=6378450.047548896 +b=6356826.621488444 +to_meter=0.3048006096012192";
+ case 26803 : return "+proj=tmerc +lat_0=41.5 +lon_0=-88.75 +k=0.999909091 +x_0=152400.3048006096 +y_0=0 +a=6378450.047548896 +b=6356826.621488444 +to_meter=0.3048006096012192";
+ case 26811 : return "+proj=lcc +lat_1=45.48333333333333 +lat_2=47.08333333333334 +lat_0=44.78333333333333 +lon_0=-87 +x_0=609601.2192024384 +y_0=0 +a=6378450.047548896 +b=6356826.621488444 +to_meter=0.3048006096012192";
+ case 26812 : return "+proj=lcc +lat_1=44.18333333333333 +lat_2=45.7 +lat_0=43.31666666666667 +lon_0=-84.33333333333333 +x_0=609601.2192024384 +y_0=0 +a=6378450.047548896 +b=6356826.621488444 +to_meter=0.3048006096012192";
+ case 26813 : return "+proj=lcc +lat_1=42.1 +lat_2=43.66666666666666 +lat_0=41.5 +lon_0=-84.33333333333333 +x_0=609601.2192024384 +y_0=0 +a=6378450.047548896 +b=6356826.621488444 +to_meter=0.3048006096012192";
+ case 26901 : return "+proj=utm +zone=1 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26902 : return "+proj=utm +zone=2 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26903 : return "+proj=utm +zone=3 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26904 : return "+proj=utm +zone=4 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26905 : return "+proj=utm +zone=5 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26906 : return "+proj=utm +zone=6 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26907 : return "+proj=utm +zone=7 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26908 : return "+proj=utm +zone=8 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26909 : return "+proj=utm +zone=9 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26910 : return "+proj=utm +zone=10 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26911 : return "+proj=utm +zone=11 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26912 : return "+proj=utm +zone=12 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26913 : return "+proj=utm +zone=13 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26914 : return "+proj=utm +zone=14 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26915 : return "+proj=utm +zone=15 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26916 : return "+proj=utm +zone=16 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26917 : return "+proj=utm +zone=17 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26918 : return "+proj=utm +zone=18 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26919 : return "+proj=utm +zone=19 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26920 : return "+proj=utm +zone=20 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26921 : return "+proj=utm +zone=21 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26922 : return "+proj=utm +zone=22 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26923 : return "+proj=utm +zone=23 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26929 : return "+proj=tmerc +lat_0=30.5 +lon_0=-85.83333333333333 +k=0.99996 +x_0=200000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26930 : return "+proj=tmerc +lat_0=30 +lon_0=-87.5 +k=0.999933333 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26931 : return "+proj=omerc +lat_0=57 +lonc=-133.6666666666667 +alpha=323.1301023611111 +k=0.9999 +x_0=5000000 +y_0=-5000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26932 : return "+proj=tmerc +lat_0=54 +lon_0=-142 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26933 : return "+proj=tmerc +lat_0=54 +lon_0=-146 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26934 : return "+proj=tmerc +lat_0=54 +lon_0=-150 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26935 : return "+proj=tmerc +lat_0=54 +lon_0=-154 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26936 : return "+proj=tmerc +lat_0=54 +lon_0=-158 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26937 : return "+proj=tmerc +lat_0=54 +lon_0=-162 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26938 : return "+proj=tmerc +lat_0=54 +lon_0=-166 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26939 : return "+proj=tmerc +lat_0=54 +lon_0=-170 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26940 : return "+proj=lcc +lat_1=53.83333333333334 +lat_2=51.83333333333334 +lat_0=51 +lon_0=-176 +x_0=1000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26941 : return "+proj=lcc +lat_1=41.66666666666666 +lat_2=40 +lat_0=39.33333333333334 +lon_0=-122 +x_0=2000000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26942 : return "+proj=lcc +lat_1=39.83333333333334 +lat_2=38.33333333333334 +lat_0=37.66666666666666 +lon_0=-122 +x_0=2000000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26943 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.06666666666667 +lat_0=36.5 +lon_0=-120.5 +x_0=2000000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26944 : return "+proj=lcc +lat_1=37.25 +lat_2=36 +lat_0=35.33333333333334 +lon_0=-119 +x_0=2000000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26945 : return "+proj=lcc +lat_1=35.46666666666667 +lat_2=34.03333333333333 +lat_0=33.5 +lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26946 : return "+proj=lcc +lat_1=33.88333333333333 +lat_2=32.78333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=2000000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26948 : return "+proj=tmerc +lat_0=31 +lon_0=-110.1666666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26949 : return "+proj=tmerc +lat_0=31 +lon_0=-111.9166666666667 +k=0.9999 +x_0=213360 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26950 : return "+proj=tmerc +lat_0=31 +lon_0=-113.75 +k=0.999933333 +x_0=213360 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26951 : return "+proj=lcc +lat_1=36.23333333333333 +lat_2=34.93333333333333 +lat_0=34.33333333333334 +lon_0=-92 +x_0=400000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26952 : return "+proj=lcc +lat_1=34.76666666666667 +lat_2=33.3 +lat_0=32.66666666666666 +lon_0=-92 +x_0=400000 +y_0=400000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26953 : return "+proj=lcc +lat_1=40.78333333333333 +lat_2=39.71666666666667 +lat_0=39.33333333333334 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26954 : return "+proj=lcc +lat_1=39.75 +lat_2=38.45 +lat_0=37.83333333333334 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26955 : return "+proj=lcc +lat_1=38.43333333333333 +lat_2=37.23333333333333 +lat_0=36.66666666666666 +lon_0=-105.5 +x_0=914401.8289 +y_0=304800.6096 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26956 : return "+proj=lcc +lat_1=41.86666666666667 +lat_2=41.2 +lat_0=40.83333333333334 +lon_0=-72.75 +x_0=304800.6096 +y_0=152400.3048 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26957 : return "+proj=tmerc +lat_0=38 +lon_0=-75.41666666666667 +k=0.999995 +x_0=200000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26958 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-81 +k=0.999941177 +x_0=200000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26959 : return "+proj=tmerc +lat_0=24.33333333333333 +lon_0=-82 +k=0.999941177 +x_0=200000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26960 : return "+proj=lcc +lat_1=30.75 +lat_2=29.58333333333333 +lat_0=29 +lon_0=-84.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26961 : return "+proj=tmerc +lat_0=18.83333333333333 +lon_0=-155.5 +k=0.999966667 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26962 : return "+proj=tmerc +lat_0=20.33333333333333 +lon_0=-156.6666666666667 +k=0.999966667 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26963 : return "+proj=tmerc +lat_0=21.16666666666667 +lon_0=-158 +k=0.99999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26964 : return "+proj=tmerc +lat_0=21.83333333333333 +lon_0=-159.5 +k=0.99999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26965 : return "+proj=tmerc +lat_0=21.66666666666667 +lon_0=-160.1666666666667 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26966 : return "+proj=tmerc +lat_0=30 +lon_0=-82.16666666666667 +k=0.9999 +x_0=200000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26967 : return "+proj=tmerc +lat_0=30 +lon_0=-84.16666666666667 +k=0.9999 +x_0=700000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26968 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-112.1666666666667 +k=0.9999473679999999 +x_0=200000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26969 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-114 +k=0.9999473679999999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26970 : return "+proj=tmerc +lat_0=41.66666666666666 +lon_0=-115.75 +k=0.999933333 +x_0=800000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26971 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-88.33333333333333 +k=0.9999749999999999 +x_0=300000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26972 : return "+proj=tmerc +lat_0=36.66666666666666 +lon_0=-90.16666666666667 +k=0.999941177 +x_0=700000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26973 : return "+proj=tmerc +lat_0=37.5 +lon_0=-85.66666666666667 +k=0.999966667 +x_0=100000 +y_0=250000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26974 : return "+proj=tmerc +lat_0=37.5 +lon_0=-87.08333333333333 +k=0.999966667 +x_0=900000 +y_0=250000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26975 : return "+proj=lcc +lat_1=43.26666666666667 +lat_2=42.06666666666667 +lat_0=41.5 +lon_0=-93.5 +x_0=1500000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26976 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.61666666666667 +lat_0=40 +lon_0=-93.5 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26977 : return "+proj=lcc +lat_1=39.78333333333333 +lat_2=38.71666666666667 +lat_0=38.33333333333334 +lon_0=-98 +x_0=400000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26978 : return "+proj=lcc +lat_1=38.56666666666667 +lat_2=37.26666666666667 +lat_0=36.66666666666666 +lon_0=-98.5 +x_0=400000 +y_0=400000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26979 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=37.96666666666667 +lat_0=37.5 +lon_0=-84.25 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26980 : return "+proj=lcc +lat_1=37.93333333333333 +lat_2=36.73333333333333 +lat_0=36.33333333333334 +lon_0=-85.75 +x_0=500000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26981 : return "+proj=lcc +lat_1=32.66666666666666 +lat_2=31.16666666666667 +lat_0=30.5 +lon_0=-92.5 +x_0=1000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26982 : return "+proj=lcc +lat_1=30.7 +lat_2=29.3 +lat_0=28.5 +lon_0=-91.33333333333333 +x_0=1000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26983 : return "+proj=tmerc +lat_0=43.66666666666666 +lon_0=-68.5 +k=0.9999 +x_0=300000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26984 : return "+proj=tmerc +lat_0=42.83333333333334 +lon_0=-70.16666666666667 +k=0.999966667 +x_0=900000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26985 : return "+proj=lcc +lat_1=39.45 +lat_2=38.3 +lat_0=37.66666666666666 +lon_0=-77 +x_0=400000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26986 : return "+proj=lcc +lat_1=42.68333333333333 +lat_2=41.71666666666667 +lat_0=41 +lon_0=-71.5 +x_0=200000 +y_0=750000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26987 : return "+proj=lcc +lat_1=41.48333333333333 +lat_2=41.28333333333333 +lat_0=41 +lon_0=-70.5 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26988 : return "+proj=lcc +lat_1=47.08333333333334 +lat_2=45.48333333333333 +lat_0=44.78333333333333 +lon_0=-87 +x_0=8000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26989 : return "+proj=lcc +lat_1=45.7 +lat_2=44.18333333333333 +lat_0=43.31666666666667 +lon_0=-84.36666666666666 +x_0=6000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26990 : return "+proj=lcc +lat_1=43.66666666666666 +lat_2=42.1 +lat_0=41.5 +lon_0=-84.36666666666666 +x_0=4000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26991 : return "+proj=lcc +lat_1=48.63333333333333 +lat_2=47.03333333333333 +lat_0=46.5 +lon_0=-93.09999999999999 +x_0=800000 +y_0=100000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26992 : return "+proj=lcc +lat_1=47.05 +lat_2=45.61666666666667 +lat_0=45 +lon_0=-94.25 +x_0=800000 +y_0=100000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26993 : return "+proj=lcc +lat_1=45.21666666666667 +lat_2=43.78333333333333 +lat_0=43 +lon_0=-94 +x_0=800000 +y_0=100000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26994 : return "+proj=tmerc +lat_0=29.5 +lon_0=-88.83333333333333 +k=0.99995 +x_0=300000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26995 : return "+proj=tmerc +lat_0=29.5 +lon_0=-90.33333333333333 +k=0.99995 +x_0=700000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26996 : return "+proj=tmerc +lat_0=35.83333333333334 +lon_0=-90.5 +k=0.999933333 +x_0=250000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26997 : return "+proj=tmerc +lat_0=35.83333333333334 +lon_0=-92.5 +k=0.999933333 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 26998 : return "+proj=tmerc +lat_0=36.16666666666666 +lon_0=-94.5 +k=0.999941177 +x_0=850000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 27037 : return "+proj=utm +zone=37 +ellps=clrk80 +units=m";
+ case 27038 : return "+proj=utm +zone=38 +ellps=clrk80 +units=m";
+ case 27039 : return "+proj=utm +zone=39 +ellps=clrk80 +units=m";
+ case 27040 : return "+proj=utm +zone=40 +ellps=clrk80 +units=m";
+ case 27120 : return "+proj=utm +zone=20 +ellps=intl +units=m";
+ case 27200 : return "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 +ellps=intl +datum=nzgd49 +units=m";
+ case 27205 : return "+proj=tmerc +lat_0=-36.87986527777778 +lon_0=174.7643393611111 +k=0.9999 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27206 : return "+proj=tmerc +lat_0=-37.76124980555556 +lon_0=176.46619725 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27207 : return "+proj=tmerc +lat_0=-38.62470277777778 +lon_0=177.8856362777778 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27208 : return "+proj=tmerc +lat_0=-39.65092930555556 +lon_0=176.6736805277778 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27209 : return "+proj=tmerc +lat_0=-39.13575830555556 +lon_0=174.22801175 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27210 : return "+proj=tmerc +lat_0=-39.51247038888889 +lon_0=175.6400368055556 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27211 : return "+proj=tmerc +lat_0=-40.24194713888889 +lon_0=175.4880996111111 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27212 : return "+proj=tmerc +lat_0=-40.92553263888889 +lon_0=175.6473496666667 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27213 : return "+proj=tmerc +lat_0=-41.30131963888888 +lon_0=174.7766231111111 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27214 : return "+proj=tmerc +lat_0=-40.71475905555556 +lon_0=172.6720465 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27215 : return "+proj=tmerc +lat_0=-41.27454472222222 +lon_0=173.2993168055555 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27216 : return "+proj=tmerc +lat_0=-41.28991152777778 +lon_0=172.1090281944444 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27217 : return "+proj=tmerc +lat_0=-41.81080286111111 +lon_0=171.5812600555556 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27218 : return "+proj=tmerc +lat_0=-42.33369427777778 +lon_0=171.5497713055556 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27219 : return "+proj=tmerc +lat_0=-42.68911658333333 +lon_0=173.0101333888889 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27220 : return "+proj=tmerc +lat_0=-41.54448666666666 +lon_0=173.8020741111111 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27221 : return "+proj=tmerc +lat_0=-42.88632236111111 +lon_0=170.9799935 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27222 : return "+proj=tmerc +lat_0=-43.11012813888889 +lon_0=170.2609258333333 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27223 : return "+proj=tmerc +lat_0=-43.97780288888889 +lon_0=168.606267 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27224 : return "+proj=tmerc +lat_0=-43.59063758333333 +lon_0=172.7271935833333 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27225 : return "+proj=tmerc +lat_0=-43.74871155555556 +lon_0=171.3607484722222 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27226 : return "+proj=tmerc +lat_0=-44.40222036111111 +lon_0=171.0572508333333 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27227 : return "+proj=tmerc +lat_0=-44.73526797222222 +lon_0=169.4677550833333 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27228 : return "+proj=tmerc +lat_0=-45.13290258333333 +lon_0=168.3986411944444 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27229 : return "+proj=tmerc +lat_0=-45.56372616666666 +lon_0=167.7388617777778 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27230 : return "+proj=tmerc +lat_0=-45.81619661111111 +lon_0=170.6285951666667 +k=1 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27231 : return "+proj=tmerc +lat_0=-45.86151336111111 +lon_0=170.2825891111111 +k=0.99996 +x_0=300000 +y_0=700000 +ellps=intl +datum=nzgd49 +units=m";
+ case 27232 : return "+proj=tmerc +lat_0=-46.60000961111111 +lon_0=168.342872 +k=1 +x_0=300002.66 +y_0=699999.58 +ellps=intl +datum=nzgd49 +units=m";
+ case 27258 : return "+proj=utm +zone=58 +south +ellps=intl +datum=nzgd49 +units=m";
+ case 27259 : return "+proj=utm +zone=59 +south +ellps=intl +datum=nzgd49 +units=m";
+ case 27260 : return "+proj=utm +zone=60 +south +ellps=intl +datum=nzgd49 +units=m";
+ case 27291 : return "+proj=tmerc +lat_0=-39 +lon_0=175.5 +k=1 +x_0=274319.5243848086 +y_0=365759.3658464114 +ellps=intl +datum=nzgd49 +to_meter=0.9143984146160287";
+ case 27292 : return "+proj=tmerc +lat_0=-44 +lon_0=171.5 +k=1 +x_0=457199.2073080143 +y_0=457199.2073080143 +ellps=intl +datum=nzgd49 +to_meter=0.9143984146160287";
+ case 27391 : return "+proj=tmerc +lat_0=58 +lon_0=-4.666666666666667 +k=1 +x_0=0 +y_0=0 +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo +units=m";
+ case 27392 : return "+proj=tmerc +lat_0=58 +lon_0=-2.333333333333333 +k=1 +x_0=0 +y_0=0 +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo +units=m";
+ case 27393 : return "+proj=tmerc +lat_0=58 +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo +units=m";
+ case 27394 : return "+proj=tmerc +lat_0=58 +lon_0=2.5 +k=1 +x_0=0 +y_0=0 +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo +units=m";
+ case 27395 : return "+proj=tmerc +lat_0=58 +lon_0=6.166666666666667 +k=1 +x_0=0 +y_0=0 +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo +units=m";
+ case 27396 : return "+proj=tmerc +lat_0=58 +lon_0=10.16666666666667 +k=1 +x_0=0 +y_0=0 +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo +units=m";
+ case 27397 : return "+proj=tmerc +lat_0=58 +lon_0=14.16666666666667 +k=1 +x_0=0 +y_0=0 +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo +units=m";
+ case 27398 : return "+proj=tmerc +lat_0=58 +lon_0=18.33333333333333 +k=1 +x_0=0 +y_0=0 +a=6377492.018 +b=6356173.508712696 +towgs84=278.3,93,474.5,7.889,0.05,-6.61,6.21 +pm=oslo +units=m";
+ case 27429 : return "+proj=utm +zone=29 +ellps=intl +units=m";
+ case 27492 : return "+proj=tmerc +lat_0=39.66666666666666 +lon_0=-8.131906111111112 +k=1 +x_0=180.598 +y_0=-86.98999999999999 +ellps=intl +units=m";
+ case 27500 : return "+proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=5.399999999999999 +k_0=0.99950908 +x_0=500000 +y_0=300000 +a=6376523 +b=6355862.933255573 +pm=paris +units=m";
+ case 27561 : return "+proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27562 : return "+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27563 : return "+proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.999877499 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27564 : return "+proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.99994471 +x_0=234.358 +y_0=185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27571 : return "+proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=1200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27572 : return "+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27573 : return "+proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.999877499 +x_0=600000 +y_0=3200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27574 : return "+proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.99994471 +x_0=234.358 +y_0=4185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27581 : return "+proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=1200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27582 : return "+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27583 : return "+proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.999877499 +x_0=600000 +y_0=3200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27584 : return "+proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.99994471 +x_0=234.358 +y_0=4185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27591 : return "+proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27592 : return "+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27593 : return "+proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.999877499 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27594 : return "+proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.99994471 +x_0=234.358 +y_0=185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m";
+ case 27700 : return "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m";
+ case 28191 : return "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m";
+ case 28192 : return "+proj=tmerc +lat_0=31.73409694444445 +lon_0=35.21208055555556 +k=1 +x_0=170251.555 +y_0=1126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m";
+ case 28193 : return "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=1126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m";
+ case 28232 : return "+proj=utm +zone=32 +south +a=6378249.2 +b=6356515 +units=m";
+ case 28348 : return "+proj=utm +zone=48 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28349 : return "+proj=utm +zone=49 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28350 : return "+proj=utm +zone=50 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28351 : return "+proj=utm +zone=51 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28352 : return "+proj=utm +zone=52 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28353 : return "+proj=utm +zone=53 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28354 : return "+proj=utm +zone=54 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28355 : return "+proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28356 : return "+proj=utm +zone=56 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28357 : return "+proj=utm +zone=57 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28358 : return "+proj=utm +zone=58 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 28402 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=2500000 +y_0=0 +ellps=krass +units=m";
+ case 28403 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=3500000 +y_0=0 +ellps=krass +units=m";
+ case 28404 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=4500000 +y_0=0 +ellps=krass +units=m";
+ case 28405 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=5500000 +y_0=0 +ellps=krass +units=m";
+ case 28406 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=6500000 +y_0=0 +ellps=krass +units=m";
+ case 28407 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=7500000 +y_0=0 +ellps=krass +units=m";
+ case 28408 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=8500000 +y_0=0 +ellps=krass +units=m";
+ case 28409 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=9500000 +y_0=0 +ellps=krass +units=m";
+ case 28410 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=10500000 +y_0=0 +ellps=krass +units=m";
+ case 28411 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=11500000 +y_0=0 +ellps=krass +units=m";
+ case 28412 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=12500000 +y_0=0 +ellps=krass +units=m";
+ case 28413 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=13500000 +y_0=0 +ellps=krass +units=m";
+ case 28414 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=14500000 +y_0=0 +ellps=krass +units=m";
+ case 28415 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=15500000 +y_0=0 +ellps=krass +units=m";
+ case 28416 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=16500000 +y_0=0 +ellps=krass +units=m";
+ case 28417 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=17500000 +y_0=0 +ellps=krass +units=m";
+ case 28418 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=18500000 +y_0=0 +ellps=krass +units=m";
+ case 28419 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=19500000 +y_0=0 +ellps=krass +units=m";
+ case 28420 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=20500000 +y_0=0 +ellps=krass +units=m";
+ case 28421 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=21500000 +y_0=0 +ellps=krass +units=m";
+ case 28422 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=22500000 +y_0=0 +ellps=krass +units=m";
+ case 28423 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=23500000 +y_0=0 +ellps=krass +units=m";
+ case 28424 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=24500000 +y_0=0 +ellps=krass +units=m";
+ case 28425 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=25500000 +y_0=0 +ellps=krass +units=m";
+ case 28426 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=26500000 +y_0=0 +ellps=krass +units=m";
+ case 28427 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=27500000 +y_0=0 +ellps=krass +units=m";
+ case 28428 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=28500000 +y_0=0 +ellps=krass +units=m";
+ case 28429 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=29500000 +y_0=0 +ellps=krass +units=m";
+ case 28430 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=30500000 +y_0=0 +ellps=krass +units=m";
+ case 28431 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=31500000 +y_0=0 +ellps=krass +units=m";
+ case 28432 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=32500000 +y_0=0 +ellps=krass +units=m";
+ case 28462 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28463 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28464 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28465 : return "+proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28466 : return "+proj=tmerc +lat_0=0 +lon_0=33 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28467 : return "+proj=tmerc +lat_0=0 +lon_0=39 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28468 : return "+proj=tmerc +lat_0=0 +lon_0=45 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28469 : return "+proj=tmerc +lat_0=0 +lon_0=51 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28470 : return "+proj=tmerc +lat_0=0 +lon_0=57 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28471 : return "+proj=tmerc +lat_0=0 +lon_0=63 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28472 : return "+proj=tmerc +lat_0=0 +lon_0=69 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28473 : return "+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28474 : return "+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28475 : return "+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28476 : return "+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28477 : return "+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28478 : return "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28479 : return "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28480 : return "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28481 : return "+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28482 : return "+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28483 : return "+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28484 : return "+proj=tmerc +lat_0=0 +lon_0=141 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28485 : return "+proj=tmerc +lat_0=0 +lon_0=147 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28486 : return "+proj=tmerc +lat_0=0 +lon_0=153 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28487 : return "+proj=tmerc +lat_0=0 +lon_0=159 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28488 : return "+proj=tmerc +lat_0=0 +lon_0=165 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28489 : return "+proj=tmerc +lat_0=0 +lon_0=171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28490 : return "+proj=tmerc +lat_0=0 +lon_0=177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28491 : return "+proj=tmerc +lat_0=0 +lon_0=-177 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28492 : return "+proj=tmerc +lat_0=0 +lon_0=-171 +k=1 +x_0=500000 +y_0=0 +ellps=krass +units=m";
+ case 28600 : return "+proj=tmerc +lat_0=24.45 +lon_0=51.21666666666667 +k=0.99999 +x_0=200000 +y_0=300000 +ellps=intl +units=m";
+ case 28991 : return "+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 28992 : return "+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +units=m";
+ case 29100 : return "+proj=poly +lat_0=0 +lon_0=-54 +x_0=5000000 +y_0=10000000 +ellps=GRS67 +units=m";
+ case 29101 : return "+proj=poly +lat_0=0 +lon_0=-54 +x_0=5000000 +y_0=10000000 +ellps=aust_SA +units=m";
+ case 29118 : return "+proj=utm +zone=18 +ellps=GRS67 +units=m";
+ case 29119 : return "+proj=utm +zone=19 +ellps=GRS67 +units=m";
+ case 29120 : return "+proj=utm +zone=20 +ellps=GRS67 +units=m";
+ case 29121 : return "+proj=utm +zone=21 +ellps=GRS67 +units=m";
+ case 29122 : return "+proj=utm +zone=22 +ellps=GRS67 +units=m";
+ case 29168 : return "+proj=utm +zone=18 +ellps=aust_SA +units=m";
+ case 29169 : return "+proj=utm +zone=19 +ellps=aust_SA +units=m";
+ case 29170 : return "+proj=utm +zone=20 +ellps=aust_SA +units=m";
+ case 29171 : return "+proj=utm +zone=21 +ellps=aust_SA +units=m";
+ case 29172 : return "+proj=utm +zone=22 +ellps=aust_SA +units=m";
+ case 29177 : return "+proj=utm +zone=17 +south +ellps=GRS67 +units=m";
+ case 29178 : return "+proj=utm +zone=18 +south +ellps=GRS67 +units=m";
+ case 29179 : return "+proj=utm +zone=19 +south +ellps=GRS67 +units=m";
+ case 29180 : return "+proj=utm +zone=20 +south +ellps=GRS67 +units=m";
+ case 29181 : return "+proj=utm +zone=21 +south +ellps=GRS67 +units=m";
+ case 29182 : return "+proj=utm +zone=22 +south +ellps=GRS67 +units=m";
+ case 29183 : return "+proj=utm +zone=23 +south +ellps=GRS67 +units=m";
+ case 29184 : return "+proj=utm +zone=24 +south +ellps=GRS67 +units=m";
+ case 29185 : return "+proj=utm +zone=25 +south +ellps=GRS67 +units=m";
+ case 29187 : return "+proj=utm +zone=17 +south +ellps=aust_SA +units=m";
+ case 29188 : return "+proj=utm +zone=18 +south +ellps=aust_SA +units=m";
+ case 29189 : return "+proj=utm +zone=19 +south +ellps=aust_SA +units=m";
+ case 29190 : return "+proj=utm +zone=20 +south +ellps=aust_SA +units=m";
+ case 29191 : return "+proj=utm +zone=21 +south +ellps=aust_SA +units=m";
+ case 29192 : return "+proj=utm +zone=22 +south +ellps=aust_SA +units=m";
+ case 29193 : return "+proj=utm +zone=23 +south +ellps=aust_SA +units=m";
+ case 29194 : return "+proj=utm +zone=24 +south +ellps=aust_SA +units=m";
+ case 29195 : return "+proj=utm +zone=25 +south +ellps=aust_SA +units=m";
+ case 29220 : return "+proj=utm +zone=20 +south +ellps=intl +towgs84=-355,21,72,0,0,0,0 +units=m";
+ case 29221 : return "+proj=utm +zone=21 +south +ellps=intl +towgs84=-355,21,72,0,0,0,0 +units=m";
+ case 29333 : return "+proj=utm +zone=33 +south +ellps=bess_nam +units=m";
+ case 29635 : return "+proj=utm +zone=35 +a=6378249.2 +b=6356515 +units=m";
+ case 29636 : return "+proj=utm +zone=36 +a=6378249.2 +b=6356515 +units=m";
+ case 29700 : return "+proj=omerc +lat_0=-18.9 +lonc=44.10000000000001 +alpha=18.9 +k=0.9995000000000001 +x_0=400000 +y_0=800000 +ellps=intl +towgs84=-189,-242,-91,0,0,0,0 +pm=paris +units=m";
+ case 29702 : return "+proj=omerc +lat_0=-18.9 +lonc=44.10000000000001 +alpha=18.9 +k=0.9995000000000001 +x_0=400000 +y_0=800000 +ellps=intl +towgs84=-189,-242,-91,0,0,0,0 +pm=paris +units=m";
+ case 29738 : return "+proj=utm +zone=38 +south +ellps=intl +towgs84=-189,-242,-91,0,0,0,0 +units=m";
+ case 29739 : return "+proj=utm +zone=39 +south +ellps=intl +towgs84=-189,-242,-91,0,0,0,0 +units=m";
+ case 29849 : return "+proj=utm +zone=49 +ellps=evrstSS +units=m";
+ case 29850 : return "+proj=utm +zone=50 +ellps=evrstSS +units=m";
+ case 29871 : return "+proj=omerc +lat_0=4 +lonc=115 +alpha=53.31582047222222 +k=0.99984 +x_0=590476.8714630401 +y_0=442857.653094361 +ellps=evrstSS +to_meter=20.11676512155263";
+ case 29872 : return "+proj=omerc +lat_0=4 +lonc=115 +alpha=53.31582047222222 +k=0.99984 +x_0=590476.8727431979 +y_0=442857.6545573985 +ellps=evrstSS +to_meter=0.3047994715386762";
+ case 29873 : return "+proj=omerc +lat_0=4 +lonc=115 +alpha=53.31582047222222 +k=0.99984 +x_0=590476.87 +y_0=442857.65 +ellps=evrstSS +units=m";
+ case 29900 : return "+proj=tmerc +lat_0=53.5 +lon_0=-8 +k=1.000035 +x_0=200000 +y_0=250000 +a=6377340.189 +b=6356034.447938534 +units=m";
+ case 29901 : return "+proj=tmerc +lat_0=53.5 +lon_0=-8 +k=1 +x_0=200000 +y_0=250000 +ellps=airy +towgs84=482.5,-130.6,564.6,-1.042,-0.214,-0.631,8.15 +units=m";
+ case 29902 : return "+proj=tmerc +lat_0=53.5 +lon_0=-8 +k=1.000035 +x_0=200000 +y_0=250000 +a=6377340.189 +b=6356034.447938534 +units=m";
+ case 29903 : return "+proj=tmerc +lat_0=53.5 +lon_0=-8 +k=1.000035 +x_0=200000 +y_0=250000 +a=6377340.189 +b=6356034.447938534 +units=m";
+ case 30161 : return "+proj=tmerc +lat_0=33 +lon_0=129.5 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30162 : return "+proj=tmerc +lat_0=33 +lon_0=131 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30163 : return "+proj=tmerc +lat_0=36 +lon_0=132.1666666666667 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30164 : return "+proj=tmerc +lat_0=33 +lon_0=133.5 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30165 : return "+proj=tmerc +lat_0=36 +lon_0=134.3333333333333 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30166 : return "+proj=tmerc +lat_0=36 +lon_0=136 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30167 : return "+proj=tmerc +lat_0=36 +lon_0=137.1666666666667 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30168 : return "+proj=tmerc +lat_0=36 +lon_0=138.5 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30169 : return "+proj=tmerc +lat_0=36 +lon_0=139.8333333333333 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30170 : return "+proj=tmerc +lat_0=40 +lon_0=140.8333333333333 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30171 : return "+proj=tmerc +lat_0=44 +lon_0=140.25 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30172 : return "+proj=tmerc +lat_0=44 +lon_0=142.25 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30173 : return "+proj=tmerc +lat_0=44 +lon_0=144.25 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30174 : return "+proj=tmerc +lat_0=26 +lon_0=142 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30175 : return "+proj=tmerc +lat_0=26 +lon_0=127.5 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30176 : return "+proj=tmerc +lat_0=26 +lon_0=124 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30177 : return "+proj=tmerc +lat_0=26 +lon_0=131 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30178 : return "+proj=tmerc +lat_0=20 +lon_0=136 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30179 : return "+proj=tmerc +lat_0=26 +lon_0=154 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ case 30200 : return "+proj=cass +lat_0=10.44166666666667 +lon_0=-61.33333333333334 +x_0=86501.46392051999 +y_0=65379.0134283 +a=6378293.645208759 +b=6356617.987679838 +to_meter=0.201166195164";
+ case 30339 : return "+proj=utm +zone=39 +ellps=helmert +units=m";
+ case 30340 : return "+proj=utm +zone=40 +ellps=helmert +units=m";
+ case 30491 : return "+proj=lcc +lat_1=36 +lat_0=36 +lon_0=2.7 +k_0=0.999625544 +x_0=500000 +y_0=300000 +a=6378249.2 +b=6356515 +towgs84=-73,-247,227,0,0,0,0 +units=m";
+ case 30492 : return "+proj=lcc +lat_1=33.3 +lat_0=33.3 +lon_0=2.7 +k_0=0.999625769 +x_0=500000 +y_0=300000 +a=6378249.2 +b=6356515 +towgs84=-73,-247,227,0,0,0,0 +units=m";
+ case 30493 : return "+proj=lcc +lat_1=36 +lat_0=36 +lon_0=2.7 +k_0=0.999625544 +x_0=500000 +y_0=300000 +a=6378249.2 +b=6356515 +units=m";
+ case 30494 : return "+proj=lcc +lat_1=33.3 +lat_0=33.3 +lon_0=2.7 +k_0=0.999625769 +x_0=500000 +y_0=300000 +a=6378249.2 +b=6356515 +units=m";
+ case 30729 : return "+proj=utm +zone=29 +ellps=clrk80 +units=m";
+ case 30730 : return "+proj=utm +zone=30 +ellps=clrk80 +units=m";
+ case 30731 : return "+proj=utm +zone=31 +ellps=clrk80 +units=m";
+ case 30732 : return "+proj=utm +zone=32 +ellps=clrk80 +units=m";
+ case 30791 : return "+proj=lcc +lat_1=36 +lat_0=36 +lon_0=2.7 +k_0=0.999625544 +x_0=500135 +y_0=300090 +ellps=clrk80 +units=m";
+ case 30792 : return "+proj=lcc +lat_1=33.3 +lat_0=33.3 +lon_0=2.7 +k_0=0.999625769 +x_0=500135 +y_0=300090 +ellps=clrk80 +units=m";
+ case 30800 : return "+proj=tmerc +lat_0=0 +lon_0=15.80827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +units=m";
+ case 31028 : return "+proj=utm +zone=28 +a=6378249.2 +b=6356515 +units=m";
+ case 31121 : return "+proj=utm +zone=21 +ellps=intl +towgs84=-265,120,-358,0,0,0,0 +units=m";
+ case 31154 : return "+proj=tmerc +lat_0=0 +lon_0=-54 +k=0.9996 +x_0=500000 +y_0=0 +ellps=intl +towgs84=-265,120,-358,0,0,0,0 +units=m";
+ case 31170 : return "+proj=tmerc +lat_0=0 +lon_0=-55.68333333333333 +k=0.9996 +x_0=500000 +y_0=0 +ellps=intl +towgs84=-265,120,-358,0,0,0,0 +units=m";
+ case 31171 : return "+proj=tmerc +lat_0=0 +lon_0=-55.68333333333333 +k=0.9999 +x_0=500000 +y_0=0 +ellps=intl +towgs84=-265,120,-358,0,0,0,0 +units=m";
+ case 31251 : return "+proj=tmerc +lat_0=0 +lon_0=28 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +pm=ferro +units=m";
+ case 31252 : return "+proj=tmerc +lat_0=0 +lon_0=31 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +pm=ferro +units=m";
+ case 31253 : return "+proj=tmerc +lat_0=0 +lon_0=34 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +pm=ferro +units=m";
+ case 31254 : return "+proj=tmerc +lat_0=0 +lon_0=10.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31255 : return "+proj=tmerc +lat_0=0 +lon_0=13.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31256 : return "+proj=tmerc +lat_0=0 +lon_0=16.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31257 : return "+proj=tmerc +lat_0=0 +lon_0=10.33333333333333 +k=1 +x_0=150000 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31258 : return "+proj=tmerc +lat_0=0 +lon_0=13.33333333333333 +k=1 +x_0=450000 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31259 : return "+proj=tmerc +lat_0=0 +lon_0=16.33333333333333 +k=1 +x_0=750000 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31265 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=5500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31266 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=1 +x_0=6500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31267 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=1 +x_0=7500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31268 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=1 +x_0=8500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31275 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=0.9999 +x_0=5500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31276 : return "+proj=tmerc +lat_0=0 +lon_0=18 +k=0.9999 +x_0=6500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31277 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=0.9999 +x_0=7500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31278 : return "+proj=tmerc +lat_0=0 +lon_0=21 +k=0.9999 +x_0=7500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31279 : return "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9999 +x_0=8500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31281 : return "+proj=tmerc +lat_0=0 +lon_0=28 +k=1 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31282 : return "+proj=tmerc +lat_0=0 +lon_0=31 +k=1 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31283 : return "+proj=tmerc +lat_0=0 +lon_0=34 +k=1 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31284 : return "+proj=tmerc +lat_0=0 +lon_0=10.33333333333333 +k=1 +x_0=150000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31285 : return "+proj=tmerc +lat_0=0 +lon_0=13.33333333333333 +k=1 +x_0=450000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31286 : return "+proj=tmerc +lat_0=0 +lon_0=16.33333333333333 +k=1 +x_0=750000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31287 : return "+proj=lcc +lat_1=49 +lat_2=46 +lat_0=47.5 +lon_0=13.33333333333333 +x_0=400000 +y_0=400000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31288 : return "+proj=tmerc +lat_0=0 +lon_0=28 +k=1 +x_0=150000 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31289 : return "+proj=tmerc +lat_0=0 +lon_0=31 +k=1 +x_0=450000 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31290 : return "+proj=tmerc +lat_0=0 +lon_0=34 +k=1 +x_0=750000 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31291 : return "+proj=tmerc +lat_0=0 +lon_0=28 +k=1 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31292 : return "+proj=tmerc +lat_0=0 +lon_0=31 +k=1 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31293 : return "+proj=tmerc +lat_0=0 +lon_0=34 +k=1 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m";
+ case 31294 : return "+proj=tmerc +lat_0=0 +lon_0=10.33333333333333 +k=1 +x_0=150000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31295 : return "+proj=tmerc +lat_0=0 +lon_0=13.33333333333333 +k=1 +x_0=450000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31296 : return "+proj=tmerc +lat_0=0 +lon_0=16.33333333333333 +k=1 +x_0=750000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31297 : return "+proj=lcc +lat_1=49 +lat_2=46 +lat_0=47.5 +lon_0=13.33333333333333 +x_0=400000 +y_0=400000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m";
+ case 31300 : return "+proj=lcc +lat_1=49.83333333333334 +lat_2=51.16666666666666 +lat_0=90 +lon_0=4.356939722222222 +x_0=150000.01256 +y_0=5400088.4378 +ellps=intl +towgs84=106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1 +units=m";
+ case 31370 : return "+proj=lcc +lat_1=51.16666723333333 +lat_2=49.8333339 +lat_0=90 +lon_0=4.367486666666666 +x_0=150000.013 +y_0=5400088.438 +ellps=intl +towgs84=106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1 +units=m";
+ case 31461 : return "+proj=tmerc +lat_0=0 +lon_0=3 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31462 : return "+proj=tmerc +lat_0=0 +lon_0=6 +k=1 +x_0=2500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31463 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31464 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31465 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=5500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31466 : return "+proj=tmerc +lat_0=0 +lon_0=6 +k=1 +x_0=2500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31467 : return "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31468 : return "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31469 : return "+proj=tmerc +lat_0=0 +lon_0=15 +k=1 +x_0=5500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m";
+ case 31528 : return "+proj=utm +zone=28 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m";
+ case 31529 : return "+proj=utm +zone=29 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m";
+ case 31600 : return "+proj=sterea +lat_0=45.9 +lon_0=25.39246588888889 +k=0.9996667 +x_0=500000 +y_0=500000 +ellps=intl +units=m";
+ case 31700 : return "+proj=sterea +lat_0=46 +lon_0=25 +k=0.99975 +x_0=500000 +y_0=500000 +ellps=krass +units=m";
+ case 31838 : return "+proj=utm +zone=38 +ellps=WGS84 +towgs84=-3.2,-5.7,2.8,0,0,0,0 +units=m";
+ case 31839 : return "+proj=utm +zone=39 +ellps=WGS84 +towgs84=-3.2,-5.7,2.8,0,0,0,0 +units=m";
+ case 31900 : return "+proj=tmerc +lat_0=0 +lon_0=48 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 31901 : return "+proj=tmerc +lat_0=0 +lon_0=48 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m";
+ case 31965 : return "+proj=utm +zone=11 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31966 : return "+proj=utm +zone=12 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31967 : return "+proj=utm +zone=13 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31968 : return "+proj=utm +zone=14 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31969 : return "+proj=utm +zone=15 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31970 : return "+proj=utm +zone=16 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31971 : return "+proj=utm +zone=17 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31972 : return "+proj=utm +zone=18 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31973 : return "+proj=utm +zone=19 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31974 : return "+proj=utm +zone=20 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31975 : return "+proj=utm +zone=21 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31976 : return "+proj=utm +zone=22 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31977 : return "+proj=utm +zone=17 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31978 : return "+proj=utm +zone=18 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31979 : return "+proj=utm +zone=19 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31980 : return "+proj=utm +zone=20 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31981 : return "+proj=utm +zone=21 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31982 : return "+proj=utm +zone=22 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31983 : return "+proj=utm +zone=23 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31984 : return "+proj=utm +zone=24 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31985 : return "+proj=utm +zone=25 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31986 : return "+proj=utm +zone=17 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31987 : return "+proj=utm +zone=18 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31988 : return "+proj=utm +zone=19 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31989 : return "+proj=utm +zone=20 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31990 : return "+proj=utm +zone=21 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31991 : return "+proj=utm +zone=22 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31992 : return "+proj=utm +zone=17 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31993 : return "+proj=utm +zone=18 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31994 : return "+proj=utm +zone=19 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31995 : return "+proj=utm +zone=20 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31996 : return "+proj=utm +zone=21 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31997 : return "+proj=utm +zone=22 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31998 : return "+proj=utm +zone=23 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 31999 : return "+proj=utm +zone=24 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 32000 : return "+proj=utm +zone=25 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ case 32001 : return "+proj=lcc +lat_1=48.71666666666667 +lat_2=47.85 +lat_0=47 +lon_0=-109.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32002 : return "+proj=lcc +lat_1=47.88333333333333 +lat_2=46.45 +lat_0=45.83333333333334 +lon_0=-109.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32003 : return "+proj=lcc +lat_1=46.4 +lat_2=44.86666666666667 +lat_0=44 +lon_0=-109.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32005 : return "+proj=lcc +lat_1=41.85 +lat_2=42.81666666666667 +lat_0=41.33333333333334 +lon_0=-100 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32006 : return "+proj=lcc +lat_1=40.28333333333333 +lat_2=41.71666666666667 +lat_0=39.66666666666666 +lon_0=-99.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32007 : return "+proj=tmerc +lat_0=34.75 +lon_0=-115.5833333333333 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32008 : return "+proj=tmerc +lat_0=34.75 +lon_0=-116.6666666666667 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32009 : return "+proj=tmerc +lat_0=34.75 +lon_0=-118.5833333333333 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32010 : return "+proj=tmerc +lat_0=42.5 +lon_0=-71.66666666666667 +k=0.999966667 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32011 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.66666666666667 +k=0.9999749999999999 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32012 : return "+proj=tmerc +lat_0=31 +lon_0=-104.3333333333333 +k=0.999909091 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32013 : return "+proj=tmerc +lat_0=31 +lon_0=-106.25 +k=0.9999 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32014 : return "+proj=tmerc +lat_0=31 +lon_0=-107.8333333333333 +k=0.999916667 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32015 : return "+proj=tmerc +lat_0=40 +lon_0=-74.33333333333333 +k=0.999966667 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32016 : return "+proj=tmerc +lat_0=40 +lon_0=-76.58333333333333 +k=0.9999375 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32017 : return "+proj=tmerc +lat_0=40 +lon_0=-78.58333333333333 +k=0.9999375 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32018 : return "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.5 +lon_0=-74 +x_0=304800.6096012192 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32019 : return "+proj=lcc +lat_1=34.33333333333334 +lat_2=36.16666666666666 +lat_0=33.75 +lon_0=-79 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32020 : return "+proj=lcc +lat_1=47.43333333333333 +lat_2=48.73333333333333 +lat_0=47 +lon_0=-100.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32021 : return "+proj=lcc +lat_1=46.18333333333333 +lat_2=47.48333333333333 +lat_0=45.66666666666666 +lon_0=-100.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32022 : return "+proj=lcc +lat_1=40.43333333333333 +lat_2=41.7 +lat_0=39.66666666666666 +lon_0=-82.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32023 : return "+proj=lcc +lat_1=38.73333333333333 +lat_2=40.03333333333333 +lat_0=38 +lon_0=-82.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32024 : return "+proj=lcc +lat_1=35.56666666666667 +lat_2=36.76666666666667 +lat_0=35 +lon_0=-98 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32025 : return "+proj=lcc +lat_1=33.93333333333333 +lat_2=35.23333333333333 +lat_0=33.33333333333334 +lon_0=-98 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32026 : return "+proj=lcc +lat_1=44.33333333333334 +lat_2=46 +lat_0=43.66666666666666 +lon_0=-120.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32027 : return "+proj=lcc +lat_1=42.33333333333334 +lat_2=44 +lat_0=41.66666666666666 +lon_0=-120.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32028 : return "+proj=lcc +lat_1=40.88333333333333 +lat_2=41.95 +lat_0=40.16666666666666 +lon_0=-77.75 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32029 : return "+proj=lcc +lat_1=39.93333333333333 +lat_2=40.8 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32030 : return "+proj=tmerc +lat_0=41.08333333333334 +lon_0=-71.5 +k=0.9999938 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32031 : return "+proj=lcc +lat_1=33.76666666666667 +lat_2=34.96666666666667 +lat_0=33 +lon_0=-81 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32033 : return "+proj=lcc +lat_1=32.33333333333334 +lat_2=33.66666666666666 +lat_0=31.83333333333333 +lon_0=-81 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32034 : return "+proj=lcc +lat_1=44.41666666666666 +lat_2=45.68333333333333 +lat_0=43.83333333333334 +lon_0=-100 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32035 : return "+proj=lcc +lat_1=42.83333333333334 +lat_2=44.4 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32036 : return "+proj=lcc +lat_1=35.25 +lat_2=36.41666666666666 +lat_0=34.66666666666666 +lon_0=-86 +x_0=30480.06096012192 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32037 : return "+proj=lcc +lat_1=34.65 +lat_2=36.18333333333333 +lat_0=34 +lon_0=-101.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32038 : return "+proj=lcc +lat_1=32.13333333333333 +lat_2=33.96666666666667 +lat_0=31.66666666666667 +lon_0=-97.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32039 : return "+proj=lcc +lat_1=30.11666666666667 +lat_2=31.88333333333333 +lat_0=29.66666666666667 +lon_0=-100.3333333333333 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32040 : return "+proj=lcc +lat_1=28.38333333333333 +lat_2=30.28333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32041 : return "+proj=lcc +lat_1=26.16666666666667 +lat_2=27.83333333333333 +lat_0=25.66666666666667 +lon_0=-98.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32042 : return "+proj=lcc +lat_1=40.71666666666667 +lat_2=41.78333333333333 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32043 : return "+proj=lcc +lat_1=39.01666666666667 +lat_2=40.65 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32044 : return "+proj=lcc +lat_1=37.21666666666667 +lat_2=38.35 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32045 : return "+proj=tmerc +lat_0=42.5 +lon_0=-72.5 +k=0.999964286 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32046 : return "+proj=lcc +lat_1=38.03333333333333 +lat_2=39.2 +lat_0=37.66666666666666 +lon_0=-78.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32047 : return "+proj=lcc +lat_1=36.76666666666667 +lat_2=37.96666666666667 +lat_0=36.33333333333334 +lon_0=-78.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32048 : return "+proj=lcc +lat_1=47.5 +lat_2=48.73333333333333 +lat_0=47 +lon_0=-120.8333333333333 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32049 : return "+proj=lcc +lat_1=45.83333333333334 +lat_2=47.33333333333334 +lat_0=45.33333333333334 +lon_0=-120.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32050 : return "+proj=lcc +lat_1=39 +lat_2=40.25 +lat_0=38.5 +lon_0=-79.5 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32051 : return "+proj=lcc +lat_1=37.48333333333333 +lat_2=38.88333333333333 +lat_0=37 +lon_0=-81 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32052 : return "+proj=lcc +lat_1=45.56666666666667 +lat_2=46.76666666666667 +lat_0=45.16666666666666 +lon_0=-90 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32053 : return "+proj=lcc +lat_1=44.25 +lat_2=45.5 +lat_0=43.83333333333334 +lon_0=-90 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32054 : return "+proj=lcc +lat_1=42.73333333333333 +lat_2=44.06666666666667 +lat_0=42 +lon_0=-90 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32055 : return "+proj=tmerc +lat_0=40.66666666666666 +lon_0=-105.1666666666667 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32056 : return "+proj=tmerc +lat_0=40.66666666666666 +lon_0=-107.3333333333333 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32057 : return "+proj=tmerc +lat_0=40.66666666666666 +lon_0=-108.75 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32058 : return "+proj=tmerc +lat_0=40.66666666666666 +lon_0=-110.0833333333333 +k=0.999941177 +x_0=152400.3048006096 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32061 : return "+proj=lcc +lat_1=16.81666666666667 +lat_0=16.81666666666667 +lon_0=-90.33333333333333 +k_0=0.99992226 +x_0=500000 +y_0=292209.579 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32062 : return "+proj=lcc +lat_1=14.9 +lat_0=14.9 +lon_0=-90.33333333333333 +k_0=0.99989906 +x_0=500000 +y_0=325992.681 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32064 : return "+proj=tmerc +lat_0=0 +lon_0=-99 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32065 : return "+proj=tmerc +lat_0=0 +lon_0=-93 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32066 : return "+proj=tmerc +lat_0=0 +lon_0=-87 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32067 : return "+proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32074 : return "+proj=tmerc +lat_0=0 +lon_0=-99 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32075 : return "+proj=tmerc +lat_0=0 +lon_0=-93 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32076 : return "+proj=tmerc +lat_0=0 +lon_0=-87 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32077 : return "+proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32081 : return "+proj=tmerc +lat_0=0 +lon_0=-53 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32082 : return "+proj=tmerc +lat_0=0 +lon_0=-56 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32083 : return "+proj=tmerc +lat_0=0 +lon_0=-58.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32084 : return "+proj=tmerc +lat_0=0 +lon_0=-61.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32085 : return "+proj=tmerc +lat_0=0 +lon_0=-64.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32086 : return "+proj=tmerc +lat_0=0 +lon_0=-67.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32098 : return "+proj=lcc +lat_1=60 +lat_2=46 +lat_0=44 +lon_0=-68.5 +x_0=0 +y_0=0 +ellps=clrk66 +datum=NAD27 +units=m";
+ case 32099 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.66666666666667 +lon_0=-91.33333333333333 +x_0=609601.2192024384 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ case 32100 : return "+proj=lcc +lat_1=49 +lat_2=45 +lat_0=44.25 +lon_0=-109.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32104 : return "+proj=lcc +lat_1=43 +lat_2=40 +lat_0=39.83333333333334 +lon_0=-100 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32107 : return "+proj=tmerc +lat_0=34.75 +lon_0=-115.5833333333333 +k=0.9999 +x_0=200000 +y_0=8000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32108 : return "+proj=tmerc +lat_0=34.75 +lon_0=-116.6666666666667 +k=0.9999 +x_0=500000 +y_0=6000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32109 : return "+proj=tmerc +lat_0=34.75 +lon_0=-118.5833333333333 +k=0.9999 +x_0=800000 +y_0=4000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32110 : return "+proj=tmerc +lat_0=42.5 +lon_0=-71.66666666666667 +k=0.999966667 +x_0=300000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32111 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32112 : return "+proj=tmerc +lat_0=31 +lon_0=-104.3333333333333 +k=0.999909091 +x_0=165000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32113 : return "+proj=tmerc +lat_0=31 +lon_0=-106.25 +k=0.9999 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32114 : return "+proj=tmerc +lat_0=31 +lon_0=-107.8333333333333 +k=0.999916667 +x_0=830000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32115 : return "+proj=tmerc +lat_0=38.83333333333334 +lon_0=-74.5 +k=0.9999 +x_0=150000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32116 : return "+proj=tmerc +lat_0=40 +lon_0=-76.58333333333333 +k=0.9999375 +x_0=250000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32117 : return "+proj=tmerc +lat_0=40 +lon_0=-78.58333333333333 +k=0.9999375 +x_0=350000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32118 : return "+proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32119 : return "+proj=lcc +lat_1=36.16666666666666 +lat_2=34.33333333333334 +lat_0=33.75 +lon_0=-79 +x_0=609601.22 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32120 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.43333333333333 +lat_0=47 +lon_0=-100.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32121 : return "+proj=lcc +lat_1=47.48333333333333 +lat_2=46.18333333333333 +lat_0=45.66666666666666 +lon_0=-100.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32122 : return "+proj=lcc +lat_1=41.7 +lat_2=40.43333333333333 +lat_0=39.66666666666666 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32123 : return "+proj=lcc +lat_1=40.03333333333333 +lat_2=38.73333333333333 +lat_0=38 +lon_0=-82.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32124 : return "+proj=lcc +lat_1=36.76666666666667 +lat_2=35.56666666666667 +lat_0=35 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32125 : return "+proj=lcc +lat_1=35.23333333333333 +lat_2=33.93333333333333 +lat_0=33.33333333333334 +lon_0=-98 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32126 : return "+proj=lcc +lat_1=46 +lat_2=44.33333333333334 +lat_0=43.66666666666666 +lon_0=-120.5 +x_0=2500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32127 : return "+proj=lcc +lat_1=44 +lat_2=42.33333333333334 +lat_0=41.66666666666666 +lon_0=-120.5 +x_0=1500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32128 : return "+proj=lcc +lat_1=41.95 +lat_2=40.88333333333333 +lat_0=40.16666666666666 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32129 : return "+proj=lcc +lat_1=40.96666666666667 +lat_2=39.93333333333333 +lat_0=39.33333333333334 +lon_0=-77.75 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32130 : return "+proj=tmerc +lat_0=41.08333333333334 +lon_0=-71.5 +k=0.99999375 +x_0=100000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32133 : return "+proj=lcc +lat_1=34.83333333333334 +lat_2=32.5 +lat_0=31.83333333333333 +lon_0=-81 +x_0=609600 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32134 : return "+proj=lcc +lat_1=45.68333333333333 +lat_2=44.41666666666666 +lat_0=43.83333333333334 +lon_0=-100 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32135 : return "+proj=lcc +lat_1=44.4 +lat_2=42.83333333333334 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32136 : return "+proj=lcc +lat_1=36.41666666666666 +lat_2=35.25 +lat_0=34.33333333333334 +lon_0=-86 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32137 : return "+proj=lcc +lat_1=36.18333333333333 +lat_2=34.65 +lat_0=34 +lon_0=-101.5 +x_0=200000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32138 : return "+proj=lcc +lat_1=33.96666666666667 +lat_2=32.13333333333333 +lat_0=31.66666666666667 +lon_0=-98.5 +x_0=600000 +y_0=2000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32139 : return "+proj=lcc +lat_1=31.88333333333333 +lat_2=30.11666666666667 +lat_0=29.66666666666667 +lon_0=-100.3333333333333 +x_0=700000 +y_0=3000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32140 : return "+proj=lcc +lat_1=30.28333333333333 +lat_2=28.38333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=4000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32141 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.66666666666667 +lon_0=-98.5 +x_0=300000 +y_0=5000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32142 : return "+proj=lcc +lat_1=41.78333333333333 +lat_2=40.71666666666667 +lat_0=40.33333333333334 +lon_0=-111.5 +x_0=500000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32143 : return "+proj=lcc +lat_1=40.65 +lat_2=39.01666666666667 +lat_0=38.33333333333334 +lon_0=-111.5 +x_0=500000 +y_0=2000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32144 : return "+proj=lcc +lat_1=38.35 +lat_2=37.21666666666667 +lat_0=36.66666666666666 +lon_0=-111.5 +x_0=500000 +y_0=3000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32145 : return "+proj=tmerc +lat_0=42.5 +lon_0=-72.5 +k=0.999964286 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32146 : return "+proj=lcc +lat_1=39.2 +lat_2=38.03333333333333 +lat_0=37.66666666666666 +lon_0=-78.5 +x_0=3500000 +y_0=2000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32147 : return "+proj=lcc +lat_1=37.96666666666667 +lat_2=36.76666666666667 +lat_0=36.33333333333334 +lon_0=-78.5 +x_0=3500000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32148 : return "+proj=lcc +lat_1=48.73333333333333 +lat_2=47.5 +lat_0=47 +lon_0=-120.8333333333333 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32149 : return "+proj=lcc +lat_1=47.33333333333334 +lat_2=45.83333333333334 +lat_0=45.33333333333334 +lon_0=-120.5 +x_0=500000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32150 : return "+proj=lcc +lat_1=40.25 +lat_2=39 +lat_0=38.5 +lon_0=-79.5 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32151 : return "+proj=lcc +lat_1=38.88333333333333 +lat_2=37.48333333333333 +lat_0=37 +lon_0=-81 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32152 : return "+proj=lcc +lat_1=46.76666666666667 +lat_2=45.56666666666667 +lat_0=45.16666666666666 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32153 : return "+proj=lcc +lat_1=45.5 +lat_2=44.25 +lat_0=43.83333333333334 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32154 : return "+proj=lcc +lat_1=44.06666666666667 +lat_2=42.73333333333333 +lat_0=42 +lon_0=-90 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32155 : return "+proj=tmerc +lat_0=40.5 +lon_0=-105.1666666666667 +k=0.9999375 +x_0=200000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32156 : return "+proj=tmerc +lat_0=40.5 +lon_0=-107.3333333333333 +k=0.9999375 +x_0=400000 +y_0=100000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32157 : return "+proj=tmerc +lat_0=40.5 +lon_0=-108.75 +k=0.9999375 +x_0=600000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32158 : return "+proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +k=0.9999375 +x_0=800000 +y_0=100000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32161 : return "+proj=lcc +lat_1=18.43333333333333 +lat_2=18.03333333333333 +lat_0=17.83333333333333 +lon_0=-66.43333333333334 +x_0=200000 +y_0=200000 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32164 : return "+proj=tmerc +lat_0=0 +lon_0=-99 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 32165 : return "+proj=tmerc +lat_0=0 +lon_0=-93 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 32166 : return "+proj=tmerc +lat_0=0 +lon_0=-87 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 32167 : return "+proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192";
+ case 32180 : return "+proj=tmerc +lat_0=0 +lon_0=-55.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32181 : return "+proj=tmerc +lat_0=0 +lon_0=-53 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32182 : return "+proj=tmerc +lat_0=0 +lon_0=-56 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32183 : return "+proj=tmerc +lat_0=0 +lon_0=-58.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32184 : return "+proj=tmerc +lat_0=0 +lon_0=-61.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32185 : return "+proj=tmerc +lat_0=0 +lon_0=-64.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32186 : return "+proj=tmerc +lat_0=0 +lon_0=-67.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32187 : return "+proj=tmerc +lat_0=0 +lon_0=-70.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32188 : return "+proj=tmerc +lat_0=0 +lon_0=-73.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32189 : return "+proj=tmerc +lat_0=0 +lon_0=-76.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32190 : return "+proj=tmerc +lat_0=0 +lon_0=-79.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32191 : return "+proj=tmerc +lat_0=0 +lon_0=-82.5 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32192 : return "+proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32193 : return "+proj=tmerc +lat_0=0 +lon_0=-84 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32194 : return "+proj=tmerc +lat_0=0 +lon_0=-87 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32195 : return "+proj=tmerc +lat_0=0 +lon_0=-90 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32196 : return "+proj=tmerc +lat_0=0 +lon_0=-93 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32197 : return "+proj=tmerc +lat_0=0 +lon_0=-96 +k=0.9999 +x_0=304800 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32198 : return "+proj=lcc +lat_1=60 +lat_2=46 +lat_0=44 +lon_0=-68.5 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32199 : return "+proj=lcc +lat_1=27.83333333333333 +lat_2=26.16666666666667 +lat_0=25.5 +lon_0=-91.33333333333333 +x_0=1000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ case 32201 : return "+proj=utm +zone=1 +ellps=WGS72 +units=m";
+ case 32202 : return "+proj=utm +zone=2 +ellps=WGS72 +units=m";
+ case 32203 : return "+proj=utm +zone=3 +ellps=WGS72 +units=m";
+ case 32204 : return "+proj=utm +zone=4 +ellps=WGS72 +units=m";
+ case 32205 : return "+proj=utm +zone=5 +ellps=WGS72 +units=m";
+ case 32206 : return "+proj=utm +zone=6 +ellps=WGS72 +units=m";
+ case 32207 : return "+proj=utm +zone=7 +ellps=WGS72 +units=m";
+ case 32208 : return "+proj=utm +zone=8 +ellps=WGS72 +units=m";
+ case 32209 : return "+proj=utm +zone=9 +ellps=WGS72 +units=m";
+ case 32210 : return "+proj=utm +zone=10 +ellps=WGS72 +units=m";
+ case 32211 : return "+proj=utm +zone=11 +ellps=WGS72 +units=m";
+ case 32212 : return "+proj=utm +zone=12 +ellps=WGS72 +units=m";
+ case 32213 : return "+proj=utm +zone=13 +ellps=WGS72 +units=m";
+ case 32214 : return "+proj=utm +zone=14 +ellps=WGS72 +units=m";
+ case 32215 : return "+proj=utm +zone=15 +ellps=WGS72 +units=m";
+ case 32216 : return "+proj=utm +zone=16 +ellps=WGS72 +units=m";
+ case 32217 : return "+proj=utm +zone=17 +ellps=WGS72 +units=m";
+ case 32218 : return "+proj=utm +zone=18 +ellps=WGS72 +units=m";
+ case 32219 : return "+proj=utm +zone=19 +ellps=WGS72 +units=m";
+ case 32220 : return "+proj=utm +zone=20 +ellps=WGS72 +units=m";
+ case 32221 : return "+proj=utm +zone=21 +ellps=WGS72 +units=m";
+ case 32222 : return "+proj=utm +zone=22 +ellps=WGS72 +units=m";
+ case 32223 : return "+proj=utm +zone=23 +ellps=WGS72 +units=m";
+ case 32224 : return "+proj=utm +zone=24 +ellps=WGS72 +units=m";
+ case 32225 : return "+proj=utm +zone=25 +ellps=WGS72 +units=m";
+ case 32226 : return "+proj=utm +zone=26 +ellps=WGS72 +units=m";
+ case 32227 : return "+proj=utm +zone=27 +ellps=WGS72 +units=m";
+ case 32228 : return "+proj=utm +zone=28 +ellps=WGS72 +units=m";
+ case 32229 : return "+proj=utm +zone=29 +ellps=WGS72 +units=m";
+ case 32230 : return "+proj=utm +zone=30 +ellps=WGS72 +units=m";
+ case 32231 : return "+proj=utm +zone=31 +ellps=WGS72 +units=m";
+ case 32232 : return "+proj=utm +zone=32 +ellps=WGS72 +units=m";
+ case 32233 : return "+proj=utm +zone=33 +ellps=WGS72 +units=m";
+ case 32234 : return "+proj=utm +zone=34 +ellps=WGS72 +units=m";
+ case 32235 : return "+proj=utm +zone=35 +ellps=WGS72 +units=m";
+ case 32236 : return "+proj=utm +zone=36 +ellps=WGS72 +units=m";
+ case 32237 : return "+proj=utm +zone=37 +ellps=WGS72 +units=m";
+ case 32238 : return "+proj=utm +zone=38 +ellps=WGS72 +units=m";
+ case 32239 : return "+proj=utm +zone=39 +ellps=WGS72 +units=m";
+ case 32240 : return "+proj=utm +zone=40 +ellps=WGS72 +units=m";
+ case 32241 : return "+proj=utm +zone=41 +ellps=WGS72 +units=m";
+ case 32242 : return "+proj=utm +zone=42 +ellps=WGS72 +units=m";
+ case 32243 : return "+proj=utm +zone=43 +ellps=WGS72 +units=m";
+ case 32244 : return "+proj=utm +zone=44 +ellps=WGS72 +units=m";
+ case 32245 : return "+proj=utm +zone=45 +ellps=WGS72 +units=m";
+ case 32246 : return "+proj=utm +zone=46 +ellps=WGS72 +units=m";
+ case 32247 : return "+proj=utm +zone=47 +ellps=WGS72 +units=m";
+ case 32248 : return "+proj=utm +zone=48 +ellps=WGS72 +units=m";
+ case 32249 : return "+proj=utm +zone=49 +ellps=WGS72 +units=m";
+ case 32250 : return "+proj=utm +zone=50 +ellps=WGS72 +units=m";
+ case 32251 : return "+proj=utm +zone=51 +ellps=WGS72 +units=m";
+ case 32252 : return "+proj=utm +zone=52 +ellps=WGS72 +units=m";
+ case 32253 : return "+proj=utm +zone=53 +ellps=WGS72 +units=m";
+ case 32254 : return "+proj=utm +zone=54 +ellps=WGS72 +units=m";
+ case 32255 : return "+proj=utm +zone=55 +ellps=WGS72 +units=m";
+ case 32256 : return "+proj=utm +zone=56 +ellps=WGS72 +units=m";
+ case 32257 : return "+proj=utm +zone=57 +ellps=WGS72 +units=m";
+ case 32258 : return "+proj=utm +zone=58 +ellps=WGS72 +units=m";
+ case 32259 : return "+proj=utm +zone=59 +ellps=WGS72 +units=m";
+ case 32260 : return "+proj=utm +zone=60 +ellps=WGS72 +units=m";
+ case 32301 : return "+proj=utm +zone=1 +south +ellps=WGS72 +units=m";
+ case 32302 : return "+proj=utm +zone=2 +south +ellps=WGS72 +units=m";
+ case 32303 : return "+proj=utm +zone=3 +south +ellps=WGS72 +units=m";
+ case 32304 : return "+proj=utm +zone=4 +south +ellps=WGS72 +units=m";
+ case 32305 : return "+proj=utm +zone=5 +south +ellps=WGS72 +units=m";
+ case 32306 : return "+proj=utm +zone=6 +south +ellps=WGS72 +units=m";
+ case 32307 : return "+proj=utm +zone=7 +south +ellps=WGS72 +units=m";
+ case 32308 : return "+proj=utm +zone=8 +south +ellps=WGS72 +units=m";
+ case 32309 : return "+proj=utm +zone=9 +south +ellps=WGS72 +units=m";
+ case 32310 : return "+proj=utm +zone=10 +south +ellps=WGS72 +units=m";
+ case 32311 : return "+proj=utm +zone=11 +south +ellps=WGS72 +units=m";
+ case 32312 : return "+proj=utm +zone=12 +south +ellps=WGS72 +units=m";
+ case 32313 : return "+proj=utm +zone=13 +south +ellps=WGS72 +units=m";
+ case 32314 : return "+proj=utm +zone=14 +south +ellps=WGS72 +units=m";
+ case 32315 : return "+proj=utm +zone=15 +south +ellps=WGS72 +units=m";
+ case 32316 : return "+proj=utm +zone=16 +south +ellps=WGS72 +units=m";
+ case 32317 : return "+proj=utm +zone=17 +south +ellps=WGS72 +units=m";
+ case 32318 : return "+proj=utm +zone=18 +south +ellps=WGS72 +units=m";
+ case 32319 : return "+proj=utm +zone=19 +south +ellps=WGS72 +units=m";
+ case 32320 : return "+proj=utm +zone=20 +south +ellps=WGS72 +units=m";
+ case 32321 : return "+proj=utm +zone=21 +south +ellps=WGS72 +units=m";
+ case 32322 : return "+proj=utm +zone=22 +south +ellps=WGS72 +units=m";
+ case 32323 : return "+proj=utm +zone=23 +south +ellps=WGS72 +units=m";
+ case 32324 : return "+proj=utm +zone=24 +south +ellps=WGS72 +units=m";
+ case 32325 : return "+proj=utm +zone=25 +south +ellps=WGS72 +units=m";
+ case 32326 : return "+proj=utm +zone=26 +south +ellps=WGS72 +units=m";
+ case 32327 : return "+proj=utm +zone=27 +south +ellps=WGS72 +units=m";
+ case 32328 : return "+proj=utm +zone=28 +south +ellps=WGS72 +units=m";
+ case 32329 : return "+proj=utm +zone=29 +south +ellps=WGS72 +units=m";
+ case 32330 : return "+proj=utm +zone=30 +south +ellps=WGS72 +units=m";
+ case 32331 : return "+proj=utm +zone=31 +south +ellps=WGS72 +units=m";
+ case 32332 : return "+proj=utm +zone=32 +south +ellps=WGS72 +units=m";
+ case 32333 : return "+proj=utm +zone=33 +south +ellps=WGS72 +units=m";
+ case 32334 : return "+proj=utm +zone=34 +south +ellps=WGS72 +units=m";
+ case 32335 : return "+proj=utm +zone=35 +south +ellps=WGS72 +units=m";
+ case 32336 : return "+proj=utm +zone=36 +south +ellps=WGS72 +units=m";
+ case 32337 : return "+proj=utm +zone=37 +south +ellps=WGS72 +units=m";
+ case 32338 : return "+proj=utm +zone=38 +south +ellps=WGS72 +units=m";
+ case 32339 : return "+proj=utm +zone=39 +south +ellps=WGS72 +units=m";
+ case 32340 : return "+proj=utm +zone=40 +south +ellps=WGS72 +units=m";
+ case 32341 : return "+proj=utm +zone=41 +south +ellps=WGS72 +units=m";
+ case 32342 : return "+proj=utm +zone=42 +south +ellps=WGS72 +units=m";
+ case 32343 : return "+proj=utm +zone=43 +south +ellps=WGS72 +units=m";
+ case 32344 : return "+proj=utm +zone=44 +south +ellps=WGS72 +units=m";
+ case 32345 : return "+proj=utm +zone=45 +south +ellps=WGS72 +units=m";
+ case 32346 : return "+proj=utm +zone=46 +south +ellps=WGS72 +units=m";
+ case 32347 : return "+proj=utm +zone=47 +south +ellps=WGS72 +units=m";
+ case 32348 : return "+proj=utm +zone=48 +south +ellps=WGS72 +units=m";
+ case 32349 : return "+proj=utm +zone=49 +south +ellps=WGS72 +units=m";
+ case 32350 : return "+proj=utm +zone=50 +south +ellps=WGS72 +units=m";
+ case 32351 : return "+proj=utm +zone=51 +south +ellps=WGS72 +units=m";
+ case 32352 : return "+proj=utm +zone=52 +south +ellps=WGS72 +units=m";
+ case 32353 : return "+proj=utm +zone=53 +south +ellps=WGS72 +units=m";
+ case 32354 : return "+proj=utm +zone=54 +south +ellps=WGS72 +units=m";
+ case 32355 : return "+proj=utm +zone=55 +south +ellps=WGS72 +units=m";
+ case 32356 : return "+proj=utm +zone=56 +south +ellps=WGS72 +units=m";
+ case 32357 : return "+proj=utm +zone=57 +south +ellps=WGS72 +units=m";
+ case 32358 : return "+proj=utm +zone=58 +south +ellps=WGS72 +units=m";
+ case 32359 : return "+proj=utm +zone=59 +south +ellps=WGS72 +units=m";
+ case 32360 : return "+proj=utm +zone=60 +south +ellps=WGS72 +units=m";
+ case 32401 : return "+proj=utm +zone=1 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32402 : return "+proj=utm +zone=2 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32403 : return "+proj=utm +zone=3 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32404 : return "+proj=utm +zone=4 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32405 : return "+proj=utm +zone=5 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32406 : return "+proj=utm +zone=6 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32407 : return "+proj=utm +zone=7 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32408 : return "+proj=utm +zone=8 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32409 : return "+proj=utm +zone=9 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32410 : return "+proj=utm +zone=10 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32411 : return "+proj=utm +zone=11 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32412 : return "+proj=utm +zone=12 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32413 : return "+proj=utm +zone=13 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32414 : return "+proj=utm +zone=14 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32415 : return "+proj=utm +zone=15 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32416 : return "+proj=utm +zone=16 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32417 : return "+proj=utm +zone=17 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32418 : return "+proj=utm +zone=18 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32419 : return "+proj=utm +zone=19 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32420 : return "+proj=utm +zone=20 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32421 : return "+proj=utm +zone=21 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32422 : return "+proj=utm +zone=22 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32423 : return "+proj=utm +zone=23 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32424 : return "+proj=utm +zone=24 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32425 : return "+proj=utm +zone=25 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32426 : return "+proj=utm +zone=26 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32427 : return "+proj=utm +zone=27 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32428 : return "+proj=utm +zone=28 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32429 : return "+proj=utm +zone=29 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32430 : return "+proj=utm +zone=30 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32431 : return "+proj=utm +zone=31 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32432 : return "+proj=utm +zone=32 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32433 : return "+proj=utm +zone=33 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32434 : return "+proj=utm +zone=34 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32435 : return "+proj=utm +zone=35 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32436 : return "+proj=utm +zone=36 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32437 : return "+proj=utm +zone=37 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32438 : return "+proj=utm +zone=38 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32439 : return "+proj=utm +zone=39 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32440 : return "+proj=utm +zone=40 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32441 : return "+proj=utm +zone=41 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32442 : return "+proj=utm +zone=42 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32443 : return "+proj=utm +zone=43 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32444 : return "+proj=utm +zone=44 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32445 : return "+proj=utm +zone=45 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32446 : return "+proj=utm +zone=46 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32447 : return "+proj=utm +zone=47 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32448 : return "+proj=utm +zone=48 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32449 : return "+proj=utm +zone=49 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32450 : return "+proj=utm +zone=50 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32451 : return "+proj=utm +zone=51 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32452 : return "+proj=utm +zone=52 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32453 : return "+proj=utm +zone=53 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32454 : return "+proj=utm +zone=54 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32455 : return "+proj=utm +zone=55 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32456 : return "+proj=utm +zone=56 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32457 : return "+proj=utm +zone=57 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32458 : return "+proj=utm +zone=58 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32459 : return "+proj=utm +zone=59 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32460 : return "+proj=utm +zone=60 +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32501 : return "+proj=utm +zone=1 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32502 : return "+proj=utm +zone=2 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32503 : return "+proj=utm +zone=3 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32504 : return "+proj=utm +zone=4 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32505 : return "+proj=utm +zone=5 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32506 : return "+proj=utm +zone=6 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32507 : return "+proj=utm +zone=7 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32508 : return "+proj=utm +zone=8 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32509 : return "+proj=utm +zone=9 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32510 : return "+proj=utm +zone=10 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32511 : return "+proj=utm +zone=11 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32512 : return "+proj=utm +zone=12 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32513 : return "+proj=utm +zone=13 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32514 : return "+proj=utm +zone=14 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32515 : return "+proj=utm +zone=15 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32516 : return "+proj=utm +zone=16 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32517 : return "+proj=utm +zone=17 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32518 : return "+proj=utm +zone=18 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32519 : return "+proj=utm +zone=19 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32520 : return "+proj=utm +zone=20 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32521 : return "+proj=utm +zone=21 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32522 : return "+proj=utm +zone=22 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32523 : return "+proj=utm +zone=23 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32524 : return "+proj=utm +zone=24 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32525 : return "+proj=utm +zone=25 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32526 : return "+proj=utm +zone=26 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32527 : return "+proj=utm +zone=27 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32528 : return "+proj=utm +zone=28 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32529 : return "+proj=utm +zone=29 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32530 : return "+proj=utm +zone=30 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32531 : return "+proj=utm +zone=31 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32532 : return "+proj=utm +zone=32 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32533 : return "+proj=utm +zone=33 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32534 : return "+proj=utm +zone=34 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32535 : return "+proj=utm +zone=35 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32536 : return "+proj=utm +zone=36 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32537 : return "+proj=utm +zone=37 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32538 : return "+proj=utm +zone=38 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32539 : return "+proj=utm +zone=39 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32540 : return "+proj=utm +zone=40 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32541 : return "+proj=utm +zone=41 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32542 : return "+proj=utm +zone=42 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32543 : return "+proj=utm +zone=43 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32544 : return "+proj=utm +zone=44 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32545 : return "+proj=utm +zone=45 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32546 : return "+proj=utm +zone=46 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32547 : return "+proj=utm +zone=47 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32548 : return "+proj=utm +zone=48 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32549 : return "+proj=utm +zone=49 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32550 : return "+proj=utm +zone=50 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32551 : return "+proj=utm +zone=51 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32552 : return "+proj=utm +zone=52 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32553 : return "+proj=utm +zone=53 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32554 : return "+proj=utm +zone=54 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32555 : return "+proj=utm +zone=55 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32556 : return "+proj=utm +zone=56 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32557 : return "+proj=utm +zone=57 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32558 : return "+proj=utm +zone=58 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32559 : return "+proj=utm +zone=59 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32560 : return "+proj=utm +zone=60 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m";
+ case 32601 : return "+proj=utm +zone=1 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32602 : return "+proj=utm +zone=2 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32603 : return "+proj=utm +zone=3 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32604 : return "+proj=utm +zone=4 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32605 : return "+proj=utm +zone=5 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32606 : return "+proj=utm +zone=6 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32607 : return "+proj=utm +zone=7 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32608 : return "+proj=utm +zone=8 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32609 : return "+proj=utm +zone=9 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32610 : return "+proj=utm +zone=10 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32611 : return "+proj=utm +zone=11 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32612 : return "+proj=utm +zone=12 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32613 : return "+proj=utm +zone=13 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32614 : return "+proj=utm +zone=14 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32615 : return "+proj=utm +zone=15 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32616 : return "+proj=utm +zone=16 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32617 : return "+proj=utm +zone=17 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32618 : return "+proj=utm +zone=18 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32619 : return "+proj=utm +zone=19 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32620 : return "+proj=utm +zone=20 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32621 : return "+proj=utm +zone=21 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32622 : return "+proj=utm +zone=22 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32623 : return "+proj=utm +zone=23 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32624 : return "+proj=utm +zone=24 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32625 : return "+proj=utm +zone=25 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32626 : return "+proj=utm +zone=26 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32627 : return "+proj=utm +zone=27 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32628 : return "+proj=utm +zone=28 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32629 : return "+proj=utm +zone=29 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32630 : return "+proj=utm +zone=30 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32631 : return "+proj=utm +zone=31 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32632 : return "+proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32633 : return "+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32634 : return "+proj=utm +zone=34 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32635 : return "+proj=utm +zone=35 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32636 : return "+proj=utm +zone=36 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32637 : return "+proj=utm +zone=37 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32638 : return "+proj=utm +zone=38 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32639 : return "+proj=utm +zone=39 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32640 : return "+proj=utm +zone=40 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32641 : return "+proj=utm +zone=41 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32642 : return "+proj=utm +zone=42 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32643 : return "+proj=utm +zone=43 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32644 : return "+proj=utm +zone=44 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32645 : return "+proj=utm +zone=45 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32646 : return "+proj=utm +zone=46 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32647 : return "+proj=utm +zone=47 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32648 : return "+proj=utm +zone=48 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32649 : return "+proj=utm +zone=49 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32650 : return "+proj=utm +zone=50 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32651 : return "+proj=utm +zone=51 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32652 : return "+proj=utm +zone=52 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32653 : return "+proj=utm +zone=53 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32654 : return "+proj=utm +zone=54 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32655 : return "+proj=utm +zone=55 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32656 : return "+proj=utm +zone=56 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32657 : return "+proj=utm +zone=57 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32658 : return "+proj=utm +zone=58 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32659 : return "+proj=utm +zone=59 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32660 : return "+proj=utm +zone=60 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32661 : return "+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32662 : return "+proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32664 : return "+proj=tmerc +lat_0=0 +lon_0=-99 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=WGS84 +datum=WGS84 +to_meter=0.3048006096012192";
+ case 32665 : return "+proj=tmerc +lat_0=0 +lon_0=-93 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=WGS84 +datum=WGS84 +to_meter=0.3048006096012192";
+ case 32666 : return "+proj=tmerc +lat_0=0 +lon_0=-87 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=WGS84 +datum=WGS84 +to_meter=0.3048006096012192";
+ case 32667 : return "+proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=WGS84 +datum=WGS84 +to_meter=0.3048006096012192";
+ case 32701 : return "+proj=utm +zone=1 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32702 : return "+proj=utm +zone=2 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32703 : return "+proj=utm +zone=3 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32704 : return "+proj=utm +zone=4 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32705 : return "+proj=utm +zone=5 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32706 : return "+proj=utm +zone=6 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32707 : return "+proj=utm +zone=7 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32708 : return "+proj=utm +zone=8 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32709 : return "+proj=utm +zone=9 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32710 : return "+proj=utm +zone=10 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32711 : return "+proj=utm +zone=11 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32712 : return "+proj=utm +zone=12 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32713 : return "+proj=utm +zone=13 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32714 : return "+proj=utm +zone=14 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32715 : return "+proj=utm +zone=15 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32716 : return "+proj=utm +zone=16 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32717 : return "+proj=utm +zone=17 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32718 : return "+proj=utm +zone=18 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32719 : return "+proj=utm +zone=19 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32720 : return "+proj=utm +zone=20 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32721 : return "+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32722 : return "+proj=utm +zone=22 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32723 : return "+proj=utm +zone=23 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32724 : return "+proj=utm +zone=24 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32725 : return "+proj=utm +zone=25 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32726 : return "+proj=utm +zone=26 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32727 : return "+proj=utm +zone=27 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32728 : return "+proj=utm +zone=28 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32729 : return "+proj=utm +zone=29 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32730 : return "+proj=utm +zone=30 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32731 : return "+proj=utm +zone=31 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32732 : return "+proj=utm +zone=32 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32733 : return "+proj=utm +zone=33 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32734 : return "+proj=utm +zone=34 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32735 : return "+proj=utm +zone=35 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32736 : return "+proj=utm +zone=36 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32737 : return "+proj=utm +zone=37 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32738 : return "+proj=utm +zone=38 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32739 : return "+proj=utm +zone=39 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32740 : return "+proj=utm +zone=40 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32741 : return "+proj=utm +zone=41 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32742 : return "+proj=utm +zone=42 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32743 : return "+proj=utm +zone=43 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32744 : return "+proj=utm +zone=44 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32745 : return "+proj=utm +zone=45 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32746 : return "+proj=utm +zone=46 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32747 : return "+proj=utm +zone=47 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32748 : return "+proj=utm +zone=48 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32749 : return "+proj=utm +zone=49 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32750 : return "+proj=utm +zone=50 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32751 : return "+proj=utm +zone=51 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32752 : return "+proj=utm +zone=52 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32753 : return "+proj=utm +zone=53 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32754 : return "+proj=utm +zone=54 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32755 : return "+proj=utm +zone=55 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32756 : return "+proj=utm +zone=56 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32757 : return "+proj=utm +zone=57 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32758 : return "+proj=utm +zone=58 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32759 : return "+proj=utm +zone=59 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32760 : return "+proj=utm +zone=60 +south +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32761 : return "+proj=stere +lat_0=-90 +lat_ts=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m";
+ case 32766 : return "+proj=tmerc +lat_0=0 +lon_0=36 +k=0.9996 +x_0=500000 +y_0=10000000 +ellps=WGS84 +datum=WGS84 +units=m";
+ }
+ return "";
+ }
+
+}
+#endif // DOXYGEN_NO_DETAIL
+
+// Overloaded function
+inline parameters init(int epsg_code)
+{
+ std::string args = detail::code_to_string(epsg_code);
+ return detail::pj_init_plus(args, false);
+}
+
+}}} // namespace boost::geometry::projection
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/epsg_traits.hpp b/src/boost/geometry/extensions/gis/projections/epsg_traits.hpp
new file mode 100644
index 0000000..0556653
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/epsg_traits.hpp
@@ -0,0 +1,43 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_EPSG_TRAITS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_EPSG_TRAITS_HPP
+
+
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+
+namespace boost { namespace geometry { namespace projection
+{
+
+/*!
+ \brief EPSG traits
+ \details With help of the EPSG traits library users can statically use projections
+ or coordinate systems specifying an EPSG code. The correct projections for transformations
+ are used automically then, still keeping static polymorphism.
+ \ingroup projection
+ \tparam EPSG epsg code
+ \tparam LL latlong point type
+ \tparam XY xy point type
+ \tparam PAR parameter type, normally not specified
+*/
+template <size_t EPSG, typename LLR, typename XY, typename PAR = parameters>
+struct epsg_traits
+{
+ // Specializations define:
+ // - type to get projection type
+ // - function par to get parameters
+};
+
+
+}}} // namespace boost::geometry::projection
+
+
+#endif
+
diff --git a/src/boost/geometry/extensions/gis/projections/factory.hpp b/src/boost/geometry/extensions/gis/projections/factory.hpp
new file mode 100644
index 0000000..38acfe7
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/factory.hpp
@@ -0,0 +1,255 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_FACTORY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_FACTORY_HPP
+
+#include <map>
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/parameters.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/aea.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/aeqd.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/airy.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/aitoff.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/august.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/bacon.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/bipc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/boggs.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/bonne.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/cass.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/cc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/cea.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/chamb.hpp> // control points XY
+#include <boost/geometry/extensions/gis/projections/proj/collg.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/crast.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/denoy.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/eck1.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/eck2.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/eck3.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/eck4.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/eck5.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/eqc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/eqdc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/fahey.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/fouc_s.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/gall.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/geocent.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/geos.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/gins8.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/gnom.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/goode.hpp> // includes two other projections
+#include <boost/geometry/extensions/gis/projections/proj/gstmerc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/hammer.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/hatano.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/krovak.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/imw_p.hpp> // xy functions after inverse
+#include <boost/geometry/extensions/gis/projections/proj/laea.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/labrd.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/lagrng.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/larr.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/lask.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/latlong.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/lcc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/lcca.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/loxim.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/lsat.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/mbtfpp.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/mbtfpq.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/mbt_fps.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/merc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/mill.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/mod_ster.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/moll.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/nell.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/nell_h.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/nocol.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/nsper.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/nzmg.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/ob_tran.hpp> // includes other projection
+#include <boost/geometry/extensions/gis/projections/proj/ocea.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/oea.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/omerc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/ortho.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/poly.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/putp2.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/putp3.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/putp4p.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/putp5.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/putp6.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/robin.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/rouss.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/rpoly.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/sconics.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/somerc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/stere.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/sterea.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/sts.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/tcc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/tcea.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/tmerc.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/tpeqd.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/urm5.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/urmfps.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/vandg.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/vandg2.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/vandg4.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/wag2.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/wag3.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/wag7.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/wink1.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/wink2.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+template <typename LatLong, typename Cartesian, typename Parameters = parameters>
+class factory : public detail::base_factory<LatLong, Cartesian, Parameters>
+{
+private:
+
+ typedef std::map
+ <
+ std::string,
+ boost::shared_ptr
+ <
+ detail::factory_entry
+ <
+ LatLong,
+ Cartesian,
+ Parameters
+ >
+ >
+ > prj_registry;
+ prj_registry m_registry;
+
+public:
+
+ factory()
+ {
+ detail::aea_init(*this);
+ detail::aeqd_init(*this);
+ detail::airy_init(*this);
+ detail::aitoff_init(*this);
+ detail::august_init(*this);
+ detail::bacon_init(*this);
+ detail::bipc_init(*this);
+ detail::boggs_init(*this);
+ detail::bonne_init(*this);
+ detail::cass_init(*this);
+ detail::cc_init(*this);
+ detail::cea_init(*this);
+ detail::chamb_init(*this);
+ detail::collg_init(*this);
+ detail::crast_init(*this);
+ detail::denoy_init(*this);
+ detail::eck1_init(*this);
+ detail::eck2_init(*this);
+ detail::eck3_init(*this);
+ detail::eck4_init(*this);
+ detail::eck5_init(*this);
+ detail::eqc_init(*this);
+ detail::eqdc_init(*this);
+ detail::fahey_init(*this);
+ detail::fouc_s_init(*this);
+ detail::gall_init(*this);
+ detail::geocent_init(*this);
+ detail::geos_init(*this);
+ detail::gins8_init(*this);
+ detail::gn_sinu_init(*this);
+ detail::gnom_init(*this);
+ detail::goode_init(*this);
+ detail::gstmerc_init(*this);
+ detail::hammer_init(*this);
+ detail::hatano_init(*this);
+ detail::krovak_init(*this);
+ detail::imw_p_init(*this);
+ detail::labrd_init(*this);
+ detail::laea_init(*this);
+ detail::lagrng_init(*this);
+ detail::larr_init(*this);
+ detail::lask_init(*this);
+ detail::latlong_init(*this);
+ detail::lcc_init(*this);
+ detail::lcca_init(*this);
+ detail::loxim_init(*this);
+ detail::lsat_init(*this);
+ detail::mbtfpp_init(*this);
+ detail::mbtfpq_init(*this);
+ detail::mbt_fps_init(*this);
+ detail::merc_init(*this);
+ detail::mill_init(*this);
+ detail::mod_ster_init(*this);
+ detail::moll_init(*this);
+ detail::nell_init(*this);
+ detail::nell_h_init(*this);
+ detail::nocol_init(*this);
+ detail::nsper_init(*this);
+ detail::nzmg_init(*this);
+ detail::ob_tran_init(*this);
+ detail::ocea_init(*this);
+ detail::oea_init(*this);
+ detail::omerc_init(*this);
+ detail::ortho_init(*this);
+ detail::poly_init(*this);
+ detail::putp2_init(*this);
+ detail::putp3_init(*this);
+ detail::putp4p_init(*this);
+ detail::putp5_init(*this);
+ detail::putp6_init(*this);
+ detail::robin_init(*this);
+ detail::rouss_init(*this);
+ detail::rpoly_init(*this);
+ detail::sconics_init(*this);
+ detail::somerc_init(*this);
+ detail::stere_init(*this);
+ detail::sterea_init(*this);
+ detail::sts_init(*this);
+ detail::tcc_init(*this);
+ detail::tcea_init(*this);
+ detail::tmerc_init(*this);
+ detail::tpeqd_init(*this);
+ detail::urm5_init(*this);
+ detail::urmfps_init(*this);
+ detail::vandg_init(*this);
+ detail::vandg2_init(*this);
+ detail::vandg4_init(*this);
+ detail::wag2_init(*this);
+ detail::wag3_init(*this);
+ detail::wag7_init(*this);
+ detail::wink1_init(*this);
+ detail::wink2_init(*this);
+ }
+
+ virtual ~factory() {}
+
+ virtual void add_to_factory(std::string const& name,
+ detail::factory_entry<LatLong, Cartesian, Parameters>* sub)
+ {
+ m_registry[name].reset(sub);
+ }
+
+ inline projection<LatLong, Cartesian>* create_new(Parameters const& parameters)
+ {
+ typename prj_registry::iterator it = m_registry.find(parameters.name);
+ if (it != m_registry.end())
+ {
+ return it->second->create_new(parameters);
+ }
+
+ return 0;
+ }
+};
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_FACTORY_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/aasincos.hpp b/src/boost/geometry/extensions/gis/projections/impl/aasincos.hpp
new file mode 100644
index 0000000..dfad0d6
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/aasincos.hpp
@@ -0,0 +1,107 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_AASINCOS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_AASINCOS_HPP
+
+
+#include <cmath>
+
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry { namespace projection
+{
+
+namespace detail
+{
+
+namespace aasincos
+{
+ static const double ONE_TOL= 1.00000000000001;
+ //static const double TOL = 0.000000001;
+ static const double ATOL = 1e-50;
+}
+
+inline double aasin(double v)
+{
+ double av = 0;
+
+ if ((av = geometry::math::abs(v)) >= 1.0)
+ {
+ if (av > aasincos::ONE_TOL)
+ {
+ throw proj_exception(-19);
+ }
+ return (v < 0.0 ? -HALFPI : HALFPI);
+ }
+
+ return asin(v);
+}
+
+inline double aacos(double v)
+{
+ double av = 0;
+
+ if ((av = geometry::math::abs(v)) >= 1.0)
+ {
+ if (av > aasincos::ONE_TOL)
+ {
+ throw proj_exception(-19);
+ }
+ return (v < 0.0 ? PI : 0.0);
+ }
+
+ return acos(v);
+}
+
+inline double asqrt(double v)
+{
+ return ((v <= 0) ? 0 : sqrt(v));
+}
+
+inline double aatan2(double n, double d)
+{
+ return ((geometry::math::abs(n) < aasincos::ATOL
+ && geometry::math::abs(d) < aasincos::ATOL) ? 0.0 : atan2(n, d));
+}
+
+
+} // namespace detail
+
+
+}}} // namespace boost::geometry::projection
+
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_AASINCOS_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/adjlon.hpp b/src/boost/geometry/extensions/gis/projections/impl/adjlon.hpp
new file mode 100644
index 0000000..2eb4dd6
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/adjlon.hpp
@@ -0,0 +1,73 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_ADJLON_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_ADJLON_HPP
+
+#include <cmath>
+
+#include <boost/math/constants/constants.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+namespace detail
+{
+
+/* reduce argument to range +/- PI */
+inline double adjlon (double lon)
+{
+ static const double SPI = 3.14159265359;
+ static const double TWOPI = 6.2831853071795864769;
+ static const double ONEPI = 3.14159265358979323846;
+
+ if (geometry::math::abs(lon) <= SPI)
+ {
+ return lon;
+ }
+
+ lon += ONEPI; /* adjust to 0..2pi rad */
+ lon -= TWOPI * std::floor(lon / TWOPI); /* remove integral # of 'revolutions'*/
+ lon -= ONEPI; /* adjust back to -pi..pi rad */
+
+ return lon;
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_ADJLON_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp b/src/boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp
new file mode 100644
index 0000000..bfb98f3
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp
@@ -0,0 +1,106 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
+
+#include <string>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/extensions/gis/projections/projection.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Base-virtual-forward
+template <typename C, typename LL, typename XY, typename P>
+class base_v_f : public projection<LL, XY>
+{
+protected:
+
+ typedef typename projection<LL, XY>::LL_T LL_T;
+ typedef typename projection<LL, XY>::XY_T XY_T;
+
+public:
+
+ base_v_f(P const& params) : m_proj(params) {}
+
+ virtual P params() const {return m_proj.params();}
+
+ virtual bool forward(LL const& ll, XY& xy) const
+ {
+ return m_proj.forward(ll, xy);
+ }
+
+ virtual void fwd(LL_T& lp_lon, LL_T& lp_lat, XY_T& xy_x, XY_T& xy_y) const
+ {
+ m_proj.fwd(lp_lon, lp_lat, xy_x, xy_y);
+ }
+
+ virtual bool inverse(XY const& xy, LL& ll) const
+ {
+ boost::ignore_unused_variable_warning(xy);
+ boost::ignore_unused_variable_warning(ll);
+
+ // exception?
+ return false;
+ }
+ virtual void inv(XY_T& xy_x, XY_T& xy_y, LL_T& lp_lon, LL_T& lp_lat) const
+ {
+ boost::ignore_unused_variable_warning(xy_x);
+ boost::ignore_unused_variable_warning(xy_y);
+ boost::ignore_unused_variable_warning(lp_lon);
+ boost::ignore_unused_variable_warning(lp_lat);
+ // exception?
+ }
+
+ virtual std::string name() const
+ {
+ return m_proj.name();
+ }
+
+protected:
+
+ C m_proj;
+};
+
+// Base-virtual-forward/inverse
+template <typename C, typename LL, typename XY, typename P>
+class base_v_fi : public base_v_f<C, LL, XY, P>
+{
+private:
+
+ typedef typename base_v_f<C, LL, XY, P>::LL_T LL_T;
+ typedef typename base_v_f<C, LL, XY, P>::XY_T XY_T;
+
+public :
+
+ base_v_fi(P const& params) : base_v_f<C, LL, XY, P>(params) {}
+
+ virtual bool inverse(XY const& xy, LL& ll) const
+ {
+ return this->m_proj.inverse(xy, ll);
+ }
+
+ void inv(XY_T& xy_x, XY_T& xy_y, LL_T& lp_lon, LL_T& lp_lat) const
+ {
+ this->m_proj.inv(xy_x, xy_y, lp_lon, lp_lat);
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/base_static.hpp b/src/boost/geometry/extensions/gis/projections/impl/base_static.hpp
new file mode 100644
index 0000000..284ca88
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/base_static.hpp
@@ -0,0 +1,105 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_STATIC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_STATIC_HPP
+
+#if defined(_MSC_VER)
+// For CRTP, *this is acceptable in constructor -> turn warning off
+#pragma warning( disable : 4355 )
+#endif // defined(_MSC_VER)
+
+
+#include <string>
+
+#include <boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_inv.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Base-template-forward
+template <typename Prj, typename LL, typename XY, typename P>
+struct base_t_f
+{
+public:
+
+ inline base_t_f(Prj const& prj, P const& params)
+ : m_par(params), m_prj(prj)
+ {}
+
+ inline P params() const {return m_par;}
+
+ inline bool forward(LL const& lp, XY& xy) const
+ {
+ try
+ {
+ pj_fwd(m_prj, m_par, lp, xy);
+ return true;
+ }
+ catch(...)
+ {
+ return false;
+ }
+ }
+
+ inline std::string name() const
+ {
+ return this->m_par.name;
+ }
+
+protected:
+
+ // Some projections do not work with float -> wrong results
+ // TODO: make traits which select <double> from int/float/double and else selects T
+
+ //typedef typename geometry::coordinate_type<LL>::type LL_T;
+ //typedef typename geometry::coordinate_type<XY>::type XY_T;
+ typedef double LL_T;
+ typedef double XY_T;
+
+ P m_par;
+ const Prj& m_prj;
+};
+
+// Base-template-forward/inverse
+template <typename Prj, typename LL, typename XY, typename P>
+struct base_t_fi : public base_t_f<Prj, LL, XY, P>
+{
+public :
+ inline base_t_fi(Prj const& prj, P const& params)
+ : base_t_f<Prj, LL, XY, P>(prj, params)
+ {}
+
+ inline bool inverse(XY const& xy, LL& lp) const
+ {
+ try
+ {
+ pj_inv(this->m_prj, this->m_par, xy, lp);
+ return true;
+ }
+ catch(...)
+ {
+ return false;
+ }
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}}} // namespace boost::geometry::projection
+
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_STATIC_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/factory_entry.hpp b/src/boost/geometry/extensions/gis/projections/impl/factory_entry.hpp
new file mode 100644
index 0000000..2fea892
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/factory_entry.hpp
@@ -0,0 +1,43 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_FACTORY_ENTRY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_FACTORY_ENTRY_HPP
+
+#include <string>
+
+#include <boost/geometry/extensions/gis/projections/projection.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+namespace detail
+{
+
+template <typename LL, typename XY, typename P>
+class factory_entry
+{
+public:
+
+ virtual ~factory_entry() {}
+ virtual projection<LL, XY>* create_new(P const& par) const = 0;
+};
+
+template <typename LL, typename XY, typename P>
+class base_factory
+{
+public:
+
+ virtual ~base_factory() {}
+ virtual void add_to_factory(std::string const& name, factory_entry<LL, XY, P>* sub) = 0;
+};
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_FACTORY_ENTRY_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/function_overloads.hpp b/src/boost/geometry/extensions/gis/projections/impl/function_overloads.hpp
new file mode 100644
index 0000000..0163a4c
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/function_overloads.hpp
@@ -0,0 +1,35 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_FUNCTION_OVERLOADS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_FUNCTION_OVERLOADS_HPP
+
+#include <cmath>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+// Functions to resolve ambiguity when compiling with coordinates of different types
+/*inline double atan2(double a, double b)
+{
+ return std::atan2(a, b);
+}
+inline double pow(double a, double b)
+{
+ return std::pow(a, b);
+}
+*/
+
+inline int int_floor(double f)
+{
+ return int(std::floor(f));
+}
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_FUNCTION_OVERLOADS_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_auth.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_auth.hpp
new file mode 100644
index 0000000..65c59a5
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_auth.hpp
@@ -0,0 +1,85 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_AUTH_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_AUTH_HPP
+
+#include <cassert>
+#include <cmath>
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+static const double P00 = .33333333333333333333;
+static const double P01 = .17222222222222222222;
+static const double P02 = .10257936507936507936;
+static const double P10 = .06388888888888888888;
+static const double P11 = .06640211640211640211;
+static const double P20 = .01641501294219154443;
+static const int APA_SIZE = 3;
+
+/* determine latitude from authalic latitude */
+inline void pj_authset(double es, double* APA)
+{
+ assert(0 != APA);
+
+ double t = 0;
+
+ // if (APA = (double *)pj_malloc(APA_SIZE * sizeof(double)))
+ {
+ APA[0] = es * P00;
+ t = es * es;
+ APA[0] += t * P01;
+ APA[1] = t * P10;
+ t *= es;
+ APA[0] += t * P02;
+ APA[1] += t * P11;
+ APA[2] = t * P20;
+ }
+}
+
+inline double pj_authlat(double beta, const double* APA)
+{
+ assert(0 != APA);
+
+ double const t = beta + beta;
+
+ return(beta + APA[0] * sin(t) + APA[1] * sin(t + t) + APA[2] * sin(t + t + t));
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_AUTH_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_datum_set.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_datum_set.hpp
new file mode 100644
index 0000000..0e889ef
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_datum_set.hpp
@@ -0,0 +1,167 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUM_SET_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUM_SET_HPP
+
+#include <string>
+#include <vector>
+
+#include <boost/algorithm/string.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/pj_datums.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_param.hpp>
+#include <boost/geometry/extensions/gis/projections/parameters.hpp>
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+
+/* SEC_TO_RAD = Pi/180/3600 */
+const double SEC_TO_RAD = 4.84813681109535993589914102357e-6;
+
+/************************************************************************/
+/* pj_datum_set() */
+/************************************************************************/
+
+inline void pj_datum_set(std::vector<pvalue>& pvalues, parameters& projdef)
+{
+ std::string name, towgs84, nadgrids;
+
+ projdef.datum_type = PJD_UNKNOWN;
+
+ /* -------------------------------------------------------------------- */
+ /* Is there a datum definition in the parameter list? If so, */
+ /* add the defining values to the parameter list. Note that */
+ /* this will append the ellipse definition as well as the */
+ /* towgs84= and related parameters. It should also be pointed */
+ /* out that the addition is permanent rather than temporary */
+ /* like most other keyword expansion so that the ellipse */
+ /* definition will last into the pj_ell_set() function called */
+ /* after this one. */
+ /* -------------------------------------------------------------------- */
+ name = pj_param(pvalues, "sdatum").s;
+ if(! name.empty())
+ {
+ /* find the datum definition */
+ const int n = sizeof(pj_datums) / sizeof(pj_datums[0]);
+ int index = -1;
+ for (int i = 0; i < n && index == -1; i++)
+ {
+ if(pj_datums[i].id == name)
+ {
+ index = i;
+ }
+ }
+
+ if (index == -1)
+ {
+ throw proj_exception(-9);
+ }
+
+ if(! pj_datums[index].ellipse_id.empty())
+ {
+ std::string entry("ellps=");
+ entry +=pj_datums[index].ellipse_id;
+ pvalues.push_back(pj_mkparam(entry));
+ }
+
+ if(! pj_datums[index].defn.empty())
+ {
+ pvalues.push_back(pj_mkparam(pj_datums[index].defn));
+ }
+ }
+
+/* -------------------------------------------------------------------- */
+/* Check for nadgrids parameter. */
+/* -------------------------------------------------------------------- */
+ nadgrids = pj_param(pvalues, "snadgrids").s;
+ towgs84 = pj_param(pvalues, "stowgs84").s;
+ if(! nadgrids.empty())
+ {
+ /* We don't actually save the value separately. It will continue
+ to exist int he param list for use in pj_apply_gridshift.c */
+
+ projdef.datum_type = PJD_GRIDSHIFT;
+ }
+
+/* -------------------------------------------------------------------- */
+/* Check for towgs84 parameter. */
+/* -------------------------------------------------------------------- */
+ else if(! towgs84.empty())
+ {
+ int parm_count = 0;
+
+ int n = sizeof(projdef.datum_params) / sizeof(projdef.datum_params[0]);
+
+ /* parse out the pvalues */
+ std::vector<std::string> parm;
+ boost::split(parm, towgs84, boost::is_any_of(" ,"));
+ for (std::vector<std::string>::const_iterator it = parm.begin();
+ it != parm.end() && parm_count < n;
+ ++it)
+ {
+ projdef.datum_params[parm_count++] = atof(it->c_str());
+ }
+
+ if( projdef.datum_params[3] != 0.0
+ || projdef.datum_params[4] != 0.0
+ || projdef.datum_params[5] != 0.0
+ || projdef.datum_params[6] != 0.0 )
+ {
+ projdef.datum_type = PJD_7PARAM;
+
+ /* transform from arc seconds to radians */
+ projdef.datum_params[3] *= SEC_TO_RAD;
+ projdef.datum_params[4] *= SEC_TO_RAD;
+ projdef.datum_params[5] *= SEC_TO_RAD;
+ /* transform from parts per million to scaling factor */
+ projdef.datum_params[6] =
+ (projdef.datum_params[6]/1000000.0) + 1;
+ }
+ else
+ {
+ projdef.datum_type = PJD_3PARAM;
+ }
+
+ /* Note that pj_init() will later switch datum_type to
+ PJD_WGS84 if shifts are all zero, and ellipsoid is WGS84 or GRS80 */
+ }
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUM_SET_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_datums.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_datums.hpp
new file mode 100644
index 0000000..31244c7
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_datums.hpp
@@ -0,0 +1,106 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUMS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUMS_HPP
+
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+/*
+ * The ellipse code must match one from pj_ellps.c. The datum id should
+ * be kept to 12 characters or less if possible. Use the official OGC
+ * datum name for the comments if available.
+ */
+
+static const PJ_DATUMS pj_datums[] =
+{
+ /* id definition ellipse comments */
+ /* -- ---------- ------- -------- */
+ { "WGS84", "towgs84=0,0,0", "WGS84", "" },
+
+ { "GGRS87", "towgs84=-199.87,74.79,246.62",
+ "GRS80", "Greek_Geodetic_Reference_System_1987" },
+
+ { "NAD83", "towgs84=0,0,0", "GRS80","North_American_Datum_1983" },
+
+ { "NAD27", "nadgrids=@conus, at alaska, at ntv2_0.gsb, at ntv1_can.dat",
+ "clrk66", "North_American_Datum_1927" },
+
+ { "potsdam", "towgs84=606.0,23.0,413.0",
+ "bessel", "Potsdam Rauenberg 1950 DHDN" },
+
+ { "carthage", "towgs84=-263.0,6.0,431.0",
+ "clark80", "Carthage 1934 Tunisia" },
+
+ { "hermannskogel", "towgs84=653.0,-212.0,449.0",
+ "bessel", "Hermannskogel" },
+
+ { "ire65", "towgs84=482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",
+ "mod_airy", "Ireland 1965" },
+
+ { "nzgd49", "towgs84=59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",
+ "intl", "New Zealand Geodetic Datum 1949" },
+
+ { "OSGB36", "towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",
+ "airy", "Airy 1830" }
+};
+
+
+static const PJ_PRIME_MERIDIANS pj_prime_meridians[] =
+{
+ /* id definition */
+ /* -- ---------- */
+ { "greenwich", "0dE" },
+ { "lisbon", "9d07'54.862\"W" },
+ { "paris", "2d20'14.025\"E" },
+ { "bogota", "74d04'51.3\"W" },
+ { "madrid", "3d41'16.58\"W" },
+ { "rome", "12d27'8.4\"E" },
+ { "bern", "7d26'22.5\"E" },
+ { "jakarta", "106d48'27.79\"E" },
+ { "ferro", "17d40'W" },
+ { "brussels", "4d22'4.71\"E" },
+ { "stockholm", "18d3'29.8\"E" },
+ { "athens", "23d42'58.815\"E" },
+ { "oslo", "10d43'22.5\"E" }
+};
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUMS_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_ell_set.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_ell_set.hpp
new file mode 100644
index 0000000..7983358
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_ell_set.hpp
@@ -0,0 +1,155 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELL_SET_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELL_SET_HPP
+
+#include <string>
+#include <vector>
+
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/pj_ellps.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_param.hpp>
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+/* set ellipsoid parameters a and es */
+static const double SIXTH = .1666666666666666667; /* 1/6 */
+static const double RA4 = .04722222222222222222; /* 17/360 */
+static const double RA6 = .02215608465608465608; /* 67/3024 */
+static const double RV4 = .06944444444444444444; /* 5/72 */
+static const double RV6 = .04243827160493827160; /* 55/1296 */
+
+/* initialize geographic shape parameters */
+inline void pj_ell_set(std::vector<pvalue>& parameters, double &a, double &es)
+{
+ int i = 0;
+ double b = 0.0;
+ double e = 0.0;
+ std::string name;
+
+ /* check for varying forms of ellipsoid input */
+ a = es = 0.;
+
+ /* R takes precedence */
+ if (pj_param(parameters, "tR").i)
+ a = pj_param(parameters, "dR").f;
+ else { /* probable elliptical figure */
+
+ /* check if ellps present and temporarily append its values to pl */
+ name = pj_param(parameters, "sellps").s;
+ if (! name.empty())
+ {
+ const int n = sizeof(pj_ellps) / sizeof(pj_ellps[0]);
+ int index = -1;
+ for (int i = 0; i < n && index == -1; i++)
+ {
+ if(pj_ellps[i].id == name)
+ {
+ index = i;
+ }
+ }
+
+ if (index == -1) { throw proj_exception(-9); }
+
+ parameters.push_back(pj_mkparam(pj_ellps[index].major));
+ parameters.push_back(pj_mkparam(pj_ellps[index].ell));
+ }
+ a = pj_param(parameters, "da").f;
+ if (pj_param(parameters, "tes").i) /* eccentricity squared */
+ es = pj_param(parameters, "des").f;
+ else if (pj_param(parameters, "te").i) { /* eccentricity */
+ e = pj_param(parameters, "de").f;
+ es = e * e;
+ } else if (pj_param(parameters, "trf").i) { /* recip flattening */
+ es = pj_param(parameters, "drf").f;
+ if (!es) {
+ throw proj_exception(-10);
+ }
+ es = 1./ es;
+ es = es * (2. - es);
+ } else if (pj_param(parameters, "tf").i) { /* flattening */
+ es = pj_param(parameters, "df").f;
+ es = es * (2. - es);
+ } else if (pj_param(parameters, "tb").i) { /* minor axis */
+ b = pj_param(parameters, "db").f;
+ es = 1. - (b * b) / (a * a);
+ } /* else es == 0. and sphere of radius a */
+ if (!b)
+ b = a * sqrt(1. - es);
+ /* following options turn ellipsoid into equivalent sphere */
+ if (pj_param(parameters, "bR_A").i) { /* sphere--area of ellipsoid */
+ a *= 1. - es * (SIXTH + es * (RA4 + es * RA6));
+ es = 0.;
+ } else if (pj_param(parameters, "bR_V").i) { /* sphere--vol. of ellipsoid */
+ a *= 1. - es * (SIXTH + es * (RV4 + es * RV6));
+ es = 0.;
+ } else if (pj_param(parameters, "bR_a").i) { /* sphere--arithmetic mean */
+ a = .5 * (a + b);
+ es = 0.;
+ } else if (pj_param(parameters, "bR_g").i) { /* sphere--geometric mean */
+ a = sqrt(a * b);
+ es = 0.;
+ } else if (pj_param(parameters, "bR_h").i) { /* sphere--harmonic mean */
+ a = 2. * a * b / (a + b);
+ es = 0.;
+ } else if ((i = pj_param(parameters, "tR_lat_a").i) || /* sphere--arith. */
+ pj_param(parameters, "tR_lat_g").i) { /* or geom. mean at latitude */
+ double tmp;
+
+ tmp = sin(pj_param(parameters, i ? "rR_lat_a" : "rR_lat_g").f);
+ if (geometry::math::abs(tmp) > HALFPI) {
+ throw proj_exception(-11);
+ }
+ tmp = 1. - es * tmp * tmp;
+ a *= i ? .5 * (1. - es + tmp) / ( tmp * sqrt(tmp)) :
+ sqrt(1. - es) / tmp;
+ es = 0.;
+ }
+ }
+
+ /* some remaining checks */
+ if (es < 0.)
+ { throw proj_exception(-12); }
+ if (a <= 0.)
+ { throw proj_exception(-13); }
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELL_SET_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_ellps.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_ellps.hpp
new file mode 100644
index 0000000..31b93d8
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_ellps.hpp
@@ -0,0 +1,93 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP
+
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+static const PJ_ELLPS pj_ellps[] =
+{
+ { "MERIT", "a=6378137.0", "rf=298.257", "MERIT 1983" },
+ { "SGS85", "a=6378136.0", "rf=298.257", "Soviet Geodetic System 85" },
+ { "GRS80", "a=6378137.0", "rf=298.257222101", "GRS 1980(IUGG, 1980)" },
+ { "IAU76", "a=6378140.0", "rf=298.257", "IAU 1976" },
+ { "airy", "a=6377563.396", "b=6356256.910", "Airy 1830" },
+ { "APL4.9", "a=6378137.0.", "rf=298.25", "Appl. Physics. 1965" },
+ { "NWL9D", "a=6378145.0.", "rf=298.25", "Naval Weapons Lab., 1965" },
+ { "mod_airy", "a=6377340.189", "b=6356034.446", "Modified Airy" },
+ { "andrae", "a=6377104.43", "rf=300.0", "Andrae 1876 (Den., Iclnd.)" },
+ { "aust_SA", "a=6378160.0", "rf=298.25", "Australian Natl & S. Amer. 1969" },
+ { "GRS67", "a=6378160.0", "rf=298.2471674270", "GRS 67(IUGG 1967)" },
+ { "bessel", "a=6377397.155", "rf=299.1528128", "Bessel 1841" },
+ { "bess_nam", "a=6377483.865", "rf=299.1528128", "Bessel 1841 (Namibia)" },
+ { "clrk66", "a=6378206.4", "b=6356583.8", "Clarke 1866" },
+ { "clrk80", "a=6378249.145", "rf=293.4663", "Clarke 1880 mod." },
+ { "CPM", "a=6375738.7", "rf=334.29", "Comm. des Poids et Mesures 1799" },
+ { "delmbr", "a=6376428.", "rf=311.5", "Delambre 1810 (Belgium)" },
+ { "engelis", "a=6378136.05", "rf=298.2566", "Engelis 1985" },
+ { "evrst30", "a=6377276.345", "rf=300.8017", "Everest 1830" },
+ { "evrst48", "a=6377304.063", "rf=300.8017", "Everest 1948" },
+ { "evrst56", "a=6377301.243", "rf=300.8017", "Everest 1956" },
+ { "evrst69", "a=6377295.664", "rf=300.8017", "Everest 1969" },
+ { "evrstSS", "a=6377298.556", "rf=300.8017", "Everest (Sabah & Sarawak)" },
+ { "fschr60", "a=6378166.", "rf=298.3", "Fischer (Mercury Datum) 1960" },
+ { "fschr60m", "a=6378155.", "rf=298.3", "Modified Fischer 1960" },
+ { "fschr68", "a=6378150.", "rf=298.3", "Fischer 1968" },
+ { "helmert", "a=6378200.", "rf=298.3", "Helmert 1906" },
+ { "hough", "a=6378270.0", "rf=297.", "Hough" },
+ { "intl", "a=6378388.0", "rf=297.", "International 1909 (Hayford)" },
+ { "krass", "a=6378245.0", "rf=298.3", "Krassovsky, 1942" },
+ { "kaula", "a=6378163.", "rf=298.24", "Kaula 1961" },
+ { "lerch", "a=6378139.", "rf=298.257", "Lerch 1979" },
+ { "mprts", "a=6397300.", "rf=191.", "Maupertius 1738" },
+ { "new_intl", "a=6378157.5", "b=6356772.2","New International 1967" },
+ { "plessis", "a=6376523.", "b=6355863.", "Plessis 1817 (France)" },
+ { "SEasia", "a=6378155.0", "b=6356773.3205", "Southeast Asia" },
+ { "walbeck", "a=6376896.0", "b=6355834.8467", "Walbeck" },
+ { "WGS60", "a=6378165.0", "rf=298.3", "WGS 60" },
+ { "WGS66", "a=6378145.0", "rf=298.25", "WGS 66" },
+ { "WGS72", "a=6378135.0", "rf=298.26", "WGS 72" },
+ { "WGS84", "a=6378137.0", "rf=298.257223563", "WGS 84" },
+ { "sphere", "a=6370997.0", "b=6370997.0", "Normal Sphere (r=6370997)" }
+};
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp
new file mode 100644
index 0000000..6218dc6
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_fwd.hpp
@@ -0,0 +1,98 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_FWD_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_FWD_HPP
+
+#include <cmath>
+
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/adjlon.hpp>
+
+/* general forward projection */
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+namespace forwrd
+{
+ static const double EPS = 1.0e-12;
+}
+
+/* forward projection entry */
+template <typename Prj, typename LL, typename XY, typename P>
+inline void pj_fwd(Prj const& prj, P const& par, LL const& ll, XY& xy)
+{
+ using namespace detail;
+
+ double lp_lon = geometry::get_as_radian<0>(ll);
+ double lp_lat = geometry::get_as_radian<1>(ll);
+ const double t = geometry::math::abs(lp_lat) - HALFPI;
+
+ /* check for forward and latitude or longitude overange */
+ if (t > forwrd::EPS || geometry::math::abs(lp_lon) > 10.)
+ {
+ throw proj_exception();
+ }
+
+ if (geometry::math::abs(t) <= forwrd::EPS)
+ {
+ lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ }
+ else if (par.geoc)
+ {
+ lp_lat = atan(par.rone_es * tan(lp_lat));
+ }
+
+ lp_lon -= par.lam0; /* compute del lp.lam */
+ if (! par.over)
+ {
+ lp_lon = adjlon(lp_lon); /* post_forward del longitude */
+ }
+
+ double x = 0;
+ double y = 0;
+
+ prj.fwd(lp_lon, lp_lat, x, y);
+ geometry::set<0>(xy, par.fr_meter * (par.a * x + par.x0));
+ geometry::set<1>(xy, par.fr_meter * (par.a * y + par.y0));
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_FWD_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_gauss.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_gauss.hpp
new file mode 100644
index 0000000..8ace7c6
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_gauss.hpp
@@ -0,0 +1,130 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP
+
+
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail { namespace gauss {
+
+
+static const int MAX_ITER = 20;
+
+struct GAUSS
+{
+ double C;
+ double K;
+ double e;
+ double ratexp;
+};
+
+static const double DEL_TOL = 1e-14;
+
+inline double srat(double esinp, double exp)
+{
+ return (pow((1.0 - esinp) / (1.0 + esinp), exp));
+}
+
+inline GAUSS gauss_ini(double e, double phi0, double &chi, double &rc)
+{
+ using std::asin;
+ using std::cos;
+ using std::sin;
+ using std::sqrt;
+ using std::tan;
+
+ double sphi = 0;
+ double cphi = 0;
+ double es = 0;
+
+ GAUSS en;
+ es = e * e;
+ en.e = e;
+ sphi = sin(phi0);
+ cphi = cos(phi0);
+ cphi *= cphi;
+
+ rc = sqrt(1.0 - es) / (1.0 - es * sphi * sphi);
+ en.C = sqrt(1.0 + es * cphi * cphi / (1.0 - es));
+ chi = asin(sphi / en.C);
+ en.ratexp = 0.5 * en.C * e;
+ en.K = tan(0.5 * chi + detail::FORTPI)
+ / (pow(tan(0.5 * phi0 + detail::FORTPI), en.C) * srat(en.e * sphi, en.ratexp));
+
+ return en;
+}
+
+template <typename T>
+inline void gauss(GAUSS const& en, T& lam, T& phi)
+{
+ phi = 2.0 * atan(en.K * pow(tan(0.5 * phi + FORTPI), en.C)
+ * srat(en.e * sin(phi), en.ratexp) ) - HALFPI;
+
+ lam *= en.C;
+}
+
+template <typename T>
+inline void inv_gauss(GAUSS const& en, T& lam, T& phi)
+{
+ lam /= en.C;
+ const double num = pow(tan(0.5 * phi + FORTPI) / en.K, 1.0 / en.C);
+
+ int i = 0;
+ for (i = MAX_ITER; i; --i)
+ {
+ const double elp_phi = 2.0 * atan(num * srat(en.e * sin(phi), - 0.5 * en.e)) - HALFPI;
+
+ if (geometry::math::abs(elp_phi - phi) < DEL_TOL)
+ {
+ break;
+ }
+ phi = elp_phi;
+ }
+
+ /* convergence failed */
+ if (!i)
+ {
+ throw proj_exception(-17);
+ }
+}
+
+}} // namespace detail::gauss
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_init.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_init.hpp
new file mode 100644
index 0000000..7c618d1
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_init.hpp
@@ -0,0 +1,301 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP
+
+#include <string>
+#include <vector>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+
+#include <boost/geometry/extensions/gis/projections/impl/pj_datum_set.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_datums.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_ell_set.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_param.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_units.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/parameters.hpp>
+
+#include <boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp>
+
+
+namespace boost { namespace geometry { namespace projection
+{
+
+
+namespace detail
+{
+
+/************************************************************************/
+/* pj_init() */
+/* */
+/* Main entry point for initialing a PJ projections */
+/* definition. Note that the projection specific function is */
+/* called to do the initial allocation so it can be created */
+/* large enough to hold projection specific parameters. */
+/************************************************************************/
+template <typename R>
+parameters pj_init(R const& arguments, bool use_defaults = true)
+{
+ parameters pin;
+ for (std::vector<std::string>::const_iterator it = boost::begin(arguments);
+ it != boost::end(arguments); it++)
+ {
+ pin.params.push_back(pj_mkparam(*it));
+ }
+
+ /* check if +init present */
+ if (pj_param(pin.params, "tinit").i)
+ {
+ // maybe TODO: handle "init" parameter
+ //if (!(curr = get_init(&arguments, curr, pj_param(pin.params, "sinit").s)))
+ }
+
+ // find projection -> implemented in projection factory
+ pin.name = pj_param(pin.params, "sproj").s;
+ //if (pin.name.empty())
+ //{ throw proj_exception(-4); }
+
+
+ // set defaults, unless inhibited
+ // GL-Addition, if use_defaults is false then defaults are ignored
+ if (use_defaults && ! pj_param(pin.params, "bno_defs").i)
+ {
+ // proj4 gets defaults from "proj_def.dat", file of 94/02/23 with a few defaults.
+ // Here manually
+ if (pin.name == "lcc")
+ {
+ pin.params.push_back(pj_mkparam("lat_1=33"));
+ pin.params.push_back(pj_mkparam("lat_2=45"));
+ }
+ else if (pin.name == "aea")
+ {
+ pin.params.push_back(pj_mkparam("lat_1=29.5"));
+ pin.params.push_back(pj_mkparam("lat_2=45.5 "));
+ }
+ else
+ {
+ //<general>ellps=WGS84
+ }
+ //curr = get_defaults(&arguments, curr, name);
+ }
+
+ /* allocate projection structure */
+ // done by constructor:
+ // pin.is_latlong = 0;
+ // pin.is_geocent = 0;
+ // pin.long_wrap_center = 0.0;
+
+ /* set datum parameters */
+ pj_datum_set(pin.params, pin);
+
+ /* set ellipsoid/sphere parameters */
+ pj_ell_set(pin.params, pin.a, pin.es);
+
+ pin.a_orig = pin.a;
+ pin.es_orig = pin.es;
+
+ pin.e = sqrt(pin.es);
+ pin.ra = 1. / pin.a;
+ pin.one_es = 1. - pin.es;
+ if (pin.one_es == 0.) { throw proj_exception(-6); }
+ pin.rone_es = 1./pin.one_es;
+
+ /* Now that we have ellipse information check for WGS84 datum */
+ if( pin.datum_type == PJD_3PARAM
+ && pin.datum_params[0] == 0.0
+ && pin.datum_params[1] == 0.0
+ && pin.datum_params[2] == 0.0
+ && pin.a == 6378137.0
+ && geometry::math::abs(pin.es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/
+ {
+ pin.datum_type = PJD_WGS84;
+ }
+
+ /* set pin.geoc coordinate system */
+ pin.geoc = (pin.es && pj_param(pin.params, "bgeoc").i);
+
+ /* over-ranging flag */
+ pin.over = pj_param(pin.params, "bover").i;
+
+ /* longitude center for wrapping */
+ pin.long_wrap_center = pj_param(pin.params, "rlon_wrap").f;
+
+ /* central meridian */
+ pin.lam0 = pj_param(pin.params, "rlon_0").f;
+
+ /* central latitude */
+ pin.phi0 = pj_param(pin.params, "rlat_0").f;
+
+ /* false easting and northing */
+ pin.x0 = pj_param(pin.params, "dx_0").f;
+ pin.y0 = pj_param(pin.params, "dy_0").f;
+
+ /* general scaling factor */
+ if (pj_param(pin.params, "tk_0").i)
+ pin.k0 = pj_param(pin.params, "dk_0").f;
+ else if (pj_param(pin.params, "tk").i)
+ pin.k0 = pj_param(pin.params, "dk").f;
+ else
+ pin.k0 = 1.;
+ if (pin.k0 <= 0.) {
+ throw proj_exception(-31);
+ }
+
+ /* set units */
+ std::string s;
+ std::string units = pj_param(pin.params, "sunits").s;
+ if (! units.empty())
+ {
+ const int n = sizeof(pj_units) / sizeof(pj_units[0]);
+ int index = -1;
+ for (int i = 0; i < n && index == -1; i++)
+ {
+ if(pj_units[i].id == units)
+ {
+ index = i;
+ }
+ }
+
+ if (index == -1) { throw proj_exception(-7); }
+ s = pj_units[index].to_meter;
+ }
+
+ if (s.empty())
+ {
+ s = pj_param(pin.params, "sto_meter").s;
+ }
+
+ if (! s.empty())
+ {
+ // TODO: IMPLEMENT SPLIT
+ pin.to_meter = atof(s.c_str());
+ //if (*s == '/') /* ratio number */
+ // pin.to_meter /= strtod(++s, 0);
+ pin.fr_meter = 1. / pin.to_meter;
+ }
+ else
+ {
+ pin.to_meter = pin.fr_meter = 1.;
+ }
+
+ /* prime meridian */
+ s.clear();
+ std::string pm = pj_param(pin.params, "spm").s;
+ if (! pm.empty())
+ {
+ std::string value;
+
+ int n = sizeof(pj_prime_meridians) / sizeof(pj_prime_meridians[0]);
+ int index = -1;
+ for (int i = 0; i < n && index == -1; i++)
+ {
+ if(pj_prime_meridians[i].id == pm)
+ {
+ value = pj_prime_meridians[i].defn;
+ index = i;
+ }
+ }
+
+ if (index == -1) { throw proj_exception(-7); }
+ if (value.empty()) { throw proj_exception(-46); }
+
+ geometry::strategy::dms_parser<true> parser;
+ pin.from_greenwich = parser(value.c_str());
+ }
+ else
+ {
+ pin.from_greenwich = 0.0;
+ }
+
+ return pin;
+}
+
+/************************************************************************/
+/* pj_init_plus() */
+/* */
+/* Same as pj_init() except it takes one argument string with */
+/* individual arguments preceeded by '+', such as "+proj=utm */
+/* +zone=11 +ellps=WGS84". */
+/************************************************************************/
+
+inline parameters pj_init_plus(std::string const& definition, bool use_defaults = true)
+{
+ static const char* sep = " +";
+
+ /* split into arguments based on '+' and trim white space */
+
+ // boost::split splits on one character, here it should be on " +", so implementation below
+ // todo: put in different routine or sort out
+ std::vector<std::string> arguments;
+ std::string def = boost::trim_copy(definition);
+ boost::trim_left_if(def, boost::is_any_of(sep));
+
+ std::string::size_type loc = def.find(sep);
+ while (loc != std::string::npos)
+ {
+ std::string par = def.substr(0, loc);
+ boost::trim(par);
+ if (! par.empty())
+ {
+ arguments.push_back(par);
+ }
+
+ def.erase(0, loc);
+ boost::trim_left_if(def, boost::is_any_of(sep));
+ loc = def.find(sep);
+ }
+
+ if (! def.empty())
+ {
+ arguments.push_back(def);
+ }
+
+ /*boost::split(arguments, definition, boost::is_any_of("+"));
+ for (std::vector<std::string>::iterator it = arguments.begin(); it != arguments.end(); it++)
+ {
+ boost::trim(*it);
+ }*/
+ return pj_init(arguments, use_defaults);
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_inv.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_inv.hpp
new file mode 100644
index 0000000..70ec6e6
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_inv.hpp
@@ -0,0 +1,80 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_INV_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PJ_INV_HPP
+
+
+
+#include <boost/geometry/extensions/gis/projections/impl/adjlon.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/util/math.hpp>
+
+/* general inverse projection */
+
+namespace boost { namespace geometry { namespace projection
+{
+
+namespace detail
+{
+
+namespace inv
+{
+ static const double EPS = 1.0e-12;
+}
+
+ /* inverse projection entry */
+template <typename PRJ, typename LL, typename XY, typename PAR>
+void pj_inv(PRJ const& prj, PAR const& par, XY const& xy, LL& ll)
+{
+ /* can't do as much preliminary checking as with forward */
+ /* descale and de-offset */
+ double xy_x = (geometry::get<0>(xy) * par.to_meter - par.x0) * par.ra;
+ double xy_y = (geometry::get<1>(xy) * par.to_meter - par.y0) * par.ra;
+ double lon = 0, lat = 0;
+ prj.inv(xy_x, xy_y, lon, lat); /* inverse project */
+ lon += par.lam0; /* reduce from del lp.lam */
+ if (!par.over)
+ lon = adjlon(lon); /* adjust longitude to CM */
+ if (par.geoc && geometry::math::abs(fabs(lat)-HALFPI) > inv::EPS)
+ lat = atan(par.one_es * tan(lat));
+
+ geometry::set_from_radian<0>(ll, lon);
+ geometry::set_from_radian<1>(ll, lat);
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp
new file mode 100644
index 0000000..8dc554a
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp
@@ -0,0 +1,111 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_MLFN_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PJ_MLFN_HPP
+
+
+
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+/* meridinal distance for ellipsoid and inverse
+** 8th degree - accurate to < 1e-5 meters when used in conjuction
+** with typical major axis values.
+** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds.
+*/
+static const double C00 = 1.;
+static const double C02 = .25;
+static const double C04 = .046875;
+static const double C06 = .01953125;
+static const double C08 = .01068115234375;
+static const double C22 = .75;
+static const double C44 = .46875;
+static const double C46 = .01302083333333333333;
+static const double C48 = .00712076822916666666;
+static const double C66 = .36458333333333333333;
+static const double C68 = .00569661458333333333;
+static const double C88 = .3076171875;
+static const double EPS = 1e-11;
+static const int MAX_ITER = 10;
+static const int EN_SIZE = 5;
+
+inline void pj_enfn(double es, double* en)
+{
+ double t; //, *en;
+
+ //if (en = (double *)pj_malloc(EN_SIZE * sizeof(double)))
+ {
+ en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));
+ en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));
+ en[2] = (t = es * es) * (C44 - es * (C46 + es * C48));
+ en[3] = (t *= es) * (C66 - es * C68);
+ en[4] = t * es * C88;
+ }
+ // return en;
+}
+
+inline double pj_mlfn(double phi, double sphi, double cphi, const double *en)
+{
+ cphi *= sphi;
+ sphi *= sphi;
+ return(en[0] * phi - cphi * (en[1] + sphi*(en[2]
+ + sphi*(en[3] + sphi*en[4]))));
+}
+
+inline double pj_inv_mlfn(double arg, double es, const double *en)
+{
+ double s, t, phi, k = 1./(1.-es);
+ int i;
+
+ phi = arg;
+ for (i = MAX_ITER; i ; --i) { /* rarely goes over 2 iterations */
+ s = sin(phi);
+ t = 1. - es * s * s;
+ phi -= t = (pj_mlfn(phi, s, cos(phi), en) - arg) * (t * sqrt(t)) * k;
+ if (geometry::math::abs(t) < EPS)
+ return phi;
+ }
+ throw proj_exception(-17);
+ return phi;
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp
new file mode 100644
index 0000000..d4c102e
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp
@@ -0,0 +1,54 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_MSFN_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PJ_MSFN_HPP
+
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+
+/* determine constant small m */
+inline double pj_msfn(double sinphi, double cosphi, double es)
+{
+ return (cosphi / sqrt (1. - es * sinphi * sinphi));
+}
+
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_param.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_param.hpp
new file mode 100644
index 0000000..e42c0ff
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_param.hpp
@@ -0,0 +1,155 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_PARAM_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PJ_PARAM_HPP
+
+
+#include <string>
+#include <vector>
+
+#include <boost/geometry/extensions/gis/geographic/strategies/dms_parser.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+
+namespace boost { namespace geometry { namespace projection {
+
+namespace detail {
+
+
+
+/* create pvalue list entry */
+inline pvalue pj_mkparam(std::string const& str)
+{
+ std::string name = str;
+ std::string value;
+ boost::trim_left_if(name, boost::is_any_of("+"));
+ std::string::size_type loc = name.find("=");
+ if (loc != std::string::npos)
+ {
+ value = name.substr(loc + 1);
+ name.erase(loc);
+ }
+
+
+ pvalue newitem;
+ newitem.param = name;
+ newitem.s = value;
+ newitem.used = 0;
+ newitem.i = atoi(value.c_str());
+ newitem.f = atof(value.c_str());
+ return newitem;
+}
+
+/************************************************************************/
+/* pj_param() */
+/* */
+/* Test for presence or get pvalue value. The first */
+/* character in `opt' is a pvalue type which can take the */
+/* values: */
+/* */
+/* `t' - test for presence, return TRUE/FALSE in pvalue.i */
+/* `i' - integer value returned in pvalue.i */
+/* `d' - simple valued real input returned in pvalue.f */
+/* `r' - degrees (DMS translation applied), returned as */
+/* radians in pvalue.f */
+/* `s' - string returned in pvalue.s */
+/* `b' - test for t/T/f/F, return in pvalue.i */
+/* */
+/************************************************************************/
+
+inline pvalue pj_param(std::vector<pvalue> const& pl, std::string opt)
+{
+ char type = opt[0];
+ opt.erase(opt.begin());
+
+ pvalue value;
+
+ /* simple linear lookup */
+ for (std::vector<pvalue>::const_iterator it = pl.begin(); it != pl.end(); it++)
+ {
+ if (it->param == opt)
+ {
+ //it->used = 1;
+ switch (type)
+ {
+ case 't':
+ value.i = 1;
+ break;
+ case 'i': /* integer input */
+ value.i = atoi(it->s.c_str());
+ break;
+ case 'd': /* simple real input */
+ value.f = atof(it->s.c_str());
+ break;
+ case 'r': /* degrees input */
+ {
+ geometry::strategy::dms_parser<true> parser;
+ value.f = parser(it->s.c_str());
+ }
+ break;
+ case 's': /* char string */
+ value.s = it->s;
+ break;
+ case 'b': /* boolean */
+ switch (it->s[0])
+ {
+ case 'F': case 'f':
+ value.i = 0;
+ break;
+ case '\0': case 'T': case 't':
+ value.i = 1;
+ break;
+ default:
+ value.i = 0;
+ break;
+ }
+ break;
+ }
+ return value;
+ }
+
+ }
+
+ value.i = 0;
+ value.f = 0.0;
+ value.s = "";
+ return value;
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp
new file mode 100644
index 0000000..4e9db63
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp
@@ -0,0 +1,73 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PHI2_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PHI2_HPP
+
+
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry { namespace projection {
+namespace detail {
+
+namespace phi2
+{
+ static const double TOL = 1.0e-10;
+ static const int N_ITER = 15;
+}
+
+inline double pj_phi2(double ts, double e)
+{
+ double eccnth, Phi, con, dphi;
+ int i;
+
+ eccnth = .5 * e;
+ Phi = HALFPI - 2. * atan (ts);
+ i = phi2::N_ITER;
+ do {
+ con = e * sin (Phi);
+ dphi = HALFPI - 2. * atan (ts * pow((1. - con) /
+ (1. + con), eccnth)) - Phi;
+ Phi += dphi;
+ } while ( geometry::math::abs(dphi) > phi2::TOL && --i);
+ if (i <= 0)
+ throw proj_exception(-18);
+ return Phi;
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp
new file mode 100644
index 0000000..fe251dc
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp
@@ -0,0 +1,84 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_QSFN_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PJ_QSFN_HPP
+
+
+namespace boost { namespace geometry { namespace projection
+{ namespace detail {
+
+/* determine small q */
+inline double pj_qsfn(double sinphi, double e, double one_es)
+{
+ static const double EPSILON = 1.0e-7;
+
+ if (e >= EPSILON)
+ {
+ double con = e * sinphi;
+ return (one_es * (sinphi / (1. - con * con) -
+ (.5 / e) * log ((1. - con) / (1. + con))));
+ } else
+ return (sinphi + sinphi);
+}
+
+
+#define MAX_C 9
+struct AUTHALIC
+{
+ double C[MAX_C], CP[MAX_C], CQ[MAX_C];
+};
+
+/**
+ * @brief determine authalic latitude
+ * @param[in] phi geographic latitude
+ * @param[in] a initialized structure pointer
+ * @return authalic latitude
+ */
+inline double proj_qsfn(double phi, const AUTHALIC& a)
+{
+ double s, s2, sum;
+ int i = MAX_C;
+
+ s = sin(phi);
+ s2 = s * s;
+ sum = a.CQ[MAX_C - 1];
+ while (--i) sum = a.CQ[i] + s2 * sum;
+ return(s * sum);
+}
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp
new file mode 100644
index 0000000..1b0e23a
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp
@@ -0,0 +1,54 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_TSFN_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PJ_TSFN_HPP
+
+
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+namespace boost { namespace geometry { namespace projection {
+namespace detail {
+
+ /* determine small t */
+ inline double pj_tsfn(double phi, double sinphi, double e)
+ {
+ sinphi *= e;
+ return (tan (.5 * (HALFPI - phi)) /
+ pow((1. - sinphi) / (1. + sinphi), .5 * e));
+ }
+
+} // namespace detail
+}}} // namespace boost::geometry::projection
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_units.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_units.hpp
new file mode 100644
index 0000000..e16647e
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_units.hpp
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_UNITS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_UNITS_HPP
+
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+namespace boost { namespace geometry { namespace projection {
+namespace detail {
+
+/* Field 2 that contains the multiplier to convert named units to meters
+** may be expressed by either a simple floating point constant or a
+** numerator/denomenator values (e.g. 1/1000) */
+
+static const PJ_UNITS pj_units[] =
+{
+ { "km", "1000.", "Kilometer" },
+ { "m", "1.", "Meter" },
+ { "dm", "1/10", "Decimeter" },
+ { "cm", "1/100", "Centimeter" },
+ { "mm", "1/1000", "Millimeter" },
+ { "kmi", "1852.0", "International Nautical Mile" },
+ { "in", "0.0254", "International Inch" },
+ { "ft", "0.3048", "International Foot" },
+ { "yd", "0.9144", "International Yard" },
+ { "mi", "1609.344", "International Statute Mile" },
+ { "fath", "1.8288", "International Fathom" },
+ { "ch", "20.1168", "International Chain" },
+ { "link", "0.201168", "International Link" },
+ { "us-in", "1./39.37", "U.S. Surveyor's Inch" },
+ { "us-ft", "0.304800609601219", "U.S. Surveyor's Foot" },
+ { "us-yd", "0.914401828803658", "U.S. Surveyor's Yard" },
+ { "us-ch", "20.11684023368047", "U.S. Surveyor's Chain" },
+ { "us-mi", "1609.347218694437", "U.S. Surveyor's Statute Mile" },
+ { "ind-yd", "0.91439523", "Indian Yard" },
+ { "ind-ft", "0.30479841", "Indian Foot" },
+ { "ind-ch", "20.11669506", "Indian Chain" }
+};
+
+} // detail
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_UNITS_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/impl/pj_zpoly1.hpp b/src/boost/geometry/extensions/gis/projections/impl/pj_zpoly1.hpp
new file mode 100644
index 0000000..787e651
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/pj_zpoly1.hpp
@@ -0,0 +1,100 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ZPOLY1_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ZPOLY1_HPP
+
+
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+
+namespace boost { namespace geometry { namespace projection { namespace detail {
+
+ /* evaluate complex polynomial */
+
+ /* note: coefficients are always from C_1 to C_n
+ ** i.e. C_0 == (0., 0)
+ ** n should always be >= 1 though no checks are made
+ */
+ inline COMPLEX
+ pj_zpoly1(COMPLEX z, COMPLEX *C, int n)
+ {
+ COMPLEX a;
+ double t;
+
+ a = *(C += n);
+ while (n-- > 0)
+ {
+ a.r = (--C)->r + z.r * (t = a.r) - z.i * a.i;
+ a.i = C->i + z.r * a.i + z.i * t;
+ }
+ a.r = z.r * (t = a.r) - z.i * a.i;
+ a.i = z.r * a.i + z.i * t;
+ return a;
+ }
+
+ /* evaluate complex polynomial and derivative */
+ inline COMPLEX
+ pj_zpolyd1(COMPLEX z, COMPLEX *C, int n, COMPLEX *der)
+ {
+ double t;
+ bool first = true;
+
+ COMPLEX a = *(C += n);
+ COMPLEX b = a;
+ while (n-- > 0)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ b.r = a.r + z.r * (t = b.r) - z.i * b.i;
+ b.i = a.i + z.r * b.i + z.i * t;
+ }
+ a.r = (--C)->r + z.r * (t = a.r) - z.i * a.i;
+ a.i = C->i + z.r * a.i + z.i * t;
+ }
+ b.r = a.r + z.r * (t = b.r) - z.i * b.i;
+ b.i = a.i + z.r * b.i + z.i * t;
+ a.r = z.r * (t = a.r) - z.i * a.i;
+ a.i = z.r * a.i + z.i * t;
+ *der = b;
+ return a;
+ }
+
+}}}} // namespace boost::geometry::projection::impl
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp b/src/boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp
new file mode 100644
index 0000000..c9768d2
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp
@@ -0,0 +1,137 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PROJ_MDIST_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PROJ_MDIST_HPP
+
+
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry { namespace projection
+{
+namespace detail
+{
+ static const int MDIST_MAX_ITER = 20;
+
+ struct MDIST
+ {
+ int nb;
+ double es;
+ double E;
+ double b[MDIST_MAX_ITER];
+ };
+
+ inline void proj_mdist_ini(double es, MDIST& b)
+ {
+ double numf, numfi, twon1, denf, denfi, ens, T, twon;
+ double den, El, Es;
+ double E[MDIST_MAX_ITER];
+ int i, j;
+
+ /* generate E(e^2) and its terms E[] */
+ ens = es;
+ numf = twon1 = denfi = 1.;
+ denf = 1.;
+ twon = 4.;
+ Es = El = E[0] = 1.;
+ for (i = 1; i < MDIST_MAX_ITER ; ++i)
+ {
+ numf *= (twon1 * twon1);
+ den = twon * denf * denf * twon1;
+ T = numf/den;
+ Es -= (E[i] = T * ens);
+ ens *= es;
+ twon *= 4.;
+ denf *= ++denfi;
+ twon1 += 2.;
+ if (Es == El) /* jump out if no change */
+ break;
+ El = Es;
+ }
+ b.nb = i - 1;
+ b.es = es;
+ b.E = Es;
+ /* generate b_n coefficients--note: collapse with prefix ratios */
+ b.b[0] = Es = 1. - Es;
+ numf = denf = 1.;
+ numfi = 2.;
+ denfi = 3.;
+ for (j = 1; j < i; ++j)
+ {
+ Es -= E[j];
+ numf *= numfi;
+ denf *= denfi;
+ b.b[j] = Es * numf / denf;
+ numfi += 2.;
+ denfi += 2.;
+ }
+ }
+ inline double proj_mdist(double phi, double sphi, double cphi, const MDIST& b)
+ {
+ double sc, sum, sphi2, D;
+ int i;
+
+ sc = sphi * cphi;
+ sphi2 = sphi * sphi;
+ D = phi * b.E - b.es * sc / sqrt(1. - b.es * sphi2);
+ sum = b.b[i = b.nb];
+ while (i) sum = b.b[--i] + sphi2 * sum;
+ return(D + sc * sum);
+ }
+ inline double proj_inv_mdist(double dist, const MDIST& b)
+ {
+ static const double TOL = 1e-14;
+ double s, t, phi, k;
+ int i;
+
+ k = 1./(1.- b.es);
+ i = MDIST_MAX_ITER;
+ phi = dist;
+ while ( i-- ) {
+ s = sin(phi);
+ t = 1. - b.es * s * s;
+ phi -= t = (proj_mdist(phi, s, cos(phi), b) - dist) *
+ (t * sqrt(t)) * k;
+ if (geometry::math::abs(t) < TOL) /* that is no change */
+ return phi;
+ }
+ /* convergence failed */
+ throw proj_exception(-17);
+ }
+} // namespace detail
+
+}}} // namespace boost::geometry::projection
+
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/impl/projects.hpp b/src/boost/geometry/extensions/gis/projections/impl/projects.hpp
new file mode 100644
index 0000000..c9d17e2
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/impl/projects.hpp
@@ -0,0 +1,184 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// This file is manually converted from PROJ4 (projects.h)
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PROJECTS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PROJECTS_HPP
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include <boost/concept_check.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+/* some useful constants */
+static const double HALFPI = 1.5707963267948966;
+static const double FORTPI = 0.78539816339744833;
+static const double PI = 3.14159265358979323846;
+static const double TWOPI = 6.2831853071795864769;
+
+static const double RAD_TO_DEG = 57.29577951308232;
+static const double DEG_TO_RAD = .0174532925199432958;
+
+static const int PJD_UNKNOWN =0;
+static const int PJD_3PARAM = 1;
+static const int PJD_7PARAM = 2;
+static const int PJD_GRIDSHIFT = 3;
+static const int PJD_WGS84 = 4; /* WGS84 (or anything considered equivelent) */
+
+
+struct pvalue
+{
+ std::string param;
+ int used;
+
+ int i;
+ double f;
+ std::string s;
+};
+
+struct pj_const_pod
+{
+ int over; /* over-range flag */
+ int geoc; /* geocentric latitude flag */
+ int is_latlong; /* proj=latlong ... not really a projection at all */
+ int is_geocent; /* proj=geocent ... not really a projection at all */
+ double
+ a, /* major axis or radius if es==0 */
+ a_orig, /* major axis before any +proj related adjustment */
+ es, /* e ^ 2 */
+ es_orig, /* es before any +proj related adjustment */
+ e, /* eccentricity */
+ ra, /* 1/A */
+ one_es, /* 1 - e^2 */
+ rone_es, /* 1/one_es */
+ lam0, phi0, /* central longitude, latitude */
+ x0, y0, /* easting and northing */
+ k0, /* general scaling factor */
+ to_meter, fr_meter; /* cartesian scaling */
+
+ int datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */
+ double datum_params[7];
+ double from_greenwich; /* prime meridian offset (in radians) */
+ double long_wrap_center; /* 0.0 for -180 to 180, actually in radians*/
+
+ // Initialize all variables to zero
+ pj_const_pod()
+ {
+ std::memset(this, 0, sizeof(pj_const_pod));
+ }
+};
+
+// PROJ4 complex. Might be replaced with std::complex
+struct COMPLEX { double r, i; };
+
+struct PJ_ELLPS
+{
+ std::string id; /* ellipse keyword name */
+ std::string major; /* a= value */
+ std::string ell; /* elliptical parameter */
+ std::string name; /* comments */
+};
+
+struct PJ_DATUMS
+{
+ std::string id; /* datum keyword */
+ std::string defn; /* ie. "to_wgs84=..." */
+ std::string ellipse_id; /* ie from ellipse table */
+ std::string comments; /* EPSG code, etc */
+};
+
+struct PJ_PRIME_MERIDIANS
+{
+ std::string id; /* prime meridian keyword */
+ std::string defn; /* offset from greenwich in DMS format. */
+};
+
+struct PJ_UNITS
+{
+ std::string id; /* units keyword */
+ std::string to_meter; /* multiply by value to get meters */
+ std::string name; /* comments */
+};
+
+struct DERIVS
+{
+ double x_l, x_p; /* derivatives of x for lambda-phi */
+ double y_l, y_p; /* derivatives of y for lambda-phi */
+};
+
+struct FACTORS
+{
+ struct DERIVS der;
+ double h, k; /* meridinal, parallel scales */
+ double omega, thetap; /* angular distortion, theta prime */
+ double conv; /* convergence */
+ double s; /* areal scale factor */
+ double a, b; /* max-min scale error */
+ int code; /* info as to analytics, see following */
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+ \brief parameters, projection parameters
+ \details This structure initializes all projections
+ \ingroup projection
+*/
+struct parameters : public detail::pj_const_pod
+{
+ std::string name;
+ std::vector<detail::pvalue> params;
+};
+
+// TODO: derived from boost::exception / make more for forward/inverse/init/setup
+class proj_exception
+{
+public:
+
+ proj_exception(int code = 0)
+ {
+ boost::ignore_unused_variable_warning(code);
+ }
+};
+
+}}} // namespace boost::geometry::projection
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PROJECTS_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/parameters.hpp b/src/boost/geometry/extensions/gis/projections/parameters.hpp
new file mode 100644
index 0000000..22c5106
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/parameters.hpp
@@ -0,0 +1,65 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PARAMETERS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PARAMETERS_HPP
+
+
+#include <string>
+#include <vector>
+
+
+#include <boost/geometry/extensions/gis/projections/impl/pj_init.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+
+namespace boost { namespace geometry { namespace projection {
+
+template <typename R>
+inline parameters init(const R& arguments)
+{
+ return detail::pj_init(arguments);
+}
+
+/*!
+\ingroup projection
+\brief Initializes a projection as a string, using the format with + and =
+\details The projection can be initialized with a string (with the same format as the PROJ4 package) for
+ convenient initialization from, for example, the command line
+\par Example
+ <tt>+proj=labrd +ellps=intl +lon_0=46d26'13.95E +lat_0=18d54S +azi=18d54 +k_0=.9995 +x_0=400000 +y_0=800000</tt>
+ for the Madagascar projection.
+\note Parameters are described in the group
+*/
+inline parameters init(const std::string& arguments)
+{
+ return detail::pj_init_plus(arguments);
+}
+
+/*!
+\ingroup projection
+\brief Overload using a const char*
+*/
+inline parameters init(const char* arguments)
+{
+ return detail::pj_init_plus(arguments);
+}
+
+
+// todo:
+/*
+parameters init(const std::map<std::string, std::string>& arguments)
+{
+ return detail::pj_init_plus(arguments);
+}
+*/
+
+
+
+}}} // namespace boost::geometry::projection
+#endif
diff --git a/src/boost/geometry/extensions/gis/projections/proj/aea.hpp b/src/boost/geometry/extensions/gis/projections/proj/aea.hpp
new file mode 100644
index 0000000..30296ca
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/aea.hpp
@@ -0,0 +1,525 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+#include <boost/geometry/extensions/gis/projections/epsg_traits.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace aea{
+ static const double EPS10 = 1.e-10;
+ static const double TOL7 = 1.e-7;
+ static const int N_ITER = 15;
+ static const double EPSILON = 1.0e-7;
+ static const double TOL = 1.0e-10;
+
+ struct par_aea
+ {
+ double ec;
+ double n;
+ double c;
+ double dd;
+ double n2;
+ double rho0;
+ double rho;
+ double phi1;
+ double phi2;
+ double en[EN_SIZE];
+ int ellips;
+ };
+
+
+
+
+
+ /* determine latitude angle phi-1 */
+ inline double
+ phi1_(double qs, double Te, double Tone_es) {
+ int i;
+ double Phi, sinpi, cospi, con, com, dphi;
+
+ Phi = asin (.5 * qs);
+ if (Te < EPSILON)
+ return( Phi );
+ i = N_ITER;
+ do {
+ sinpi = sin (Phi);
+ cospi = cos (Phi);
+ con = Te * sinpi;
+ com = 1. - con * con;
+ dphi = .5 * com * com / cospi * (qs / Tone_es -
+ sinpi / com + .5 / Te * log ((1. - con) /
+ (1. + con)));
+ Phi += dphi;
+ } while (fabs(dphi) > TOL && --i);
+ return( i ? Phi : HUGE_VAL );
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_aea_ellipsoid : public base_t_fi<base_aea_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ mutable par_aea m_proj_parm;
+
+ inline base_aea_ellipsoid(const Parameters& par)
+ : base_t_fi<base_aea_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if ((this->m_proj_parm.rho = this->m_proj_parm.c - (this->m_proj_parm.ellips ? this->m_proj_parm.n * pj_qsfn(sin(lp_lat),
+ this->m_par.e, this->m_par.one_es) : this->m_proj_parm.n2 * sin(lp_lat))) < 0.) throw proj_exception();
+ this->m_proj_parm.rho = this->m_proj_parm.dd * sqrt(this->m_proj_parm.rho);
+ xy_x = this->m_proj_parm.rho * sin( lp_lon *= this->m_proj_parm.n );
+ xy_y = this->m_proj_parm.rho0 - this->m_proj_parm.rho * cos(lp_lon);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ if( (this->m_proj_parm.rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0 ) {
+ if (this->m_proj_parm.n < 0.) {
+ this->m_proj_parm.rho = -this->m_proj_parm.rho;
+ xy_x = -xy_x;
+ xy_y = -xy_y;
+ }
+ lp_lat = this->m_proj_parm.rho / this->m_proj_parm.dd;
+ if (this->m_proj_parm.ellips) {
+ lp_lat = (this->m_proj_parm.c - lp_lat * lp_lat) / this->m_proj_parm.n;
+ if (fabs(this->m_proj_parm.ec - fabs(lp_lat)) > TOL7) {
+ if ((lp_lat = phi1_(lp_lat, this->m_par.e, this->m_par.one_es)) == HUGE_VAL)
+ throw proj_exception();
+ } else
+ lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ } else if (fabs(lp_lat = (this->m_proj_parm.c - lp_lat * lp_lat) / this->m_proj_parm.n2) <= 1.)
+ lp_lat = asin(lp_lat);
+ else
+ lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ } else {
+ lp_lon = 0.;
+ lp_lat = this->m_proj_parm.n > 0. ? HALFPI : - HALFPI;
+ }
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_aea& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ double cosphi, sinphi;
+ int secant;
+ if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10) throw proj_exception(-21);
+ proj_parm.n = sinphi = sin(proj_parm.phi1);
+ cosphi = cos(proj_parm.phi1);
+ secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10;
+ if( (proj_parm.ellips = (par.es > 0.))) {
+ double ml1, m1;
+ pj_enfn(par.es, proj_parm.en);
+ m1 = pj_msfn(sinphi, cosphi, par.es);
+ ml1 = pj_qsfn(sinphi, par.e, par.one_es);
+ if (secant) { /* secant cone */
+ double ml2, m2;
+ sinphi = sin(proj_parm.phi2);
+ cosphi = cos(proj_parm.phi2);
+ m2 = pj_msfn(sinphi, cosphi, par.es);
+ ml2 = pj_qsfn(sinphi, par.e, par.one_es);
+ proj_parm.n = (m1 * m1 - m2 * m2) / (ml2 - ml1);
+ }
+ proj_parm.ec = 1. - .5 * par.one_es * log((1. - par.e) /
+ (1. + par.e)) / par.e;
+ proj_parm.c = m1 * m1 + proj_parm.n * ml1;
+ proj_parm.dd = 1. / proj_parm.n;
+ proj_parm.rho0 = proj_parm.dd * sqrt(proj_parm.c - proj_parm.n * pj_qsfn(sin(par.phi0),
+ par.e, par.one_es));
+ } else {
+ if (secant) proj_parm.n = .5 * (proj_parm.n + sin(proj_parm.phi2));
+ proj_parm.n2 = proj_parm.n + proj_parm.n;
+ proj_parm.c = cosphi * cosphi + proj_parm.n2 * sinphi;
+ proj_parm.dd = 1. / proj_parm.n;
+ proj_parm.rho0 = proj_parm.dd * sqrt(proj_parm.c - proj_parm.n2 * sin(par.phi0));
+ }
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+
+ // Albers Equal Area
+ template <typename Parameters>
+ void setup_aea(Parameters& par, par_aea& proj_parm)
+ {
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ proj_parm.phi2 = pj_param(par.params, "rlat_2").f;
+ setup(par, proj_parm);
+ }
+
+ // Lambert Equal Area Conic
+ template <typename Parameters>
+ void setup_leac(Parameters& par, par_aea& proj_parm)
+ {
+ proj_parm.phi2 = pj_param(par.params, "rlat_1").f;
+ proj_parm.phi1 = pj_param(par.params, "bsouth").i ? - HALFPI: HALFPI;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::aea
+ #endif // doxygen
+
+ /*!
+ \brief Albers Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ - lat_1= lat_2=
+ \par Example
+ \image html ex_aea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct aea_ellipsoid : public detail::aea::base_aea_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline aea_ellipsoid(const Parameters& par) : detail::aea::base_aea_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::aea::setup_aea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Lambert Equal Area Conic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ - lat_1= south
+ \par Example
+ \image html ex_leac.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct leac_ellipsoid : public detail::aea::base_aea_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline leac_ellipsoid(const Parameters& par) : detail::aea::base_aea_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::aea::setup_leac(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class aea_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<aea_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class leac_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<leac_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void aea_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("aea", new aea_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("leac", new leac_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ // Create EPSG specializations
+ // (Proof of Concept, only for some)
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2964, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=clrk66 +datum=NAD27 +to_meter=0.3048006096012192";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3005, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=50 +lat_2=58.5 +lat_0=45 +lon_0=-126 +x_0=1000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3083, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=6000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3085, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=6000000 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3086, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=24 +lat_2=31.5 +lat_0=24 +lon_0=-84 +x_0=400000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3087, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=24 +lat_2=31.5 +lat_0=24 +lon_0=-84 +x_0=400000 +y_0=0 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3153, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=50 +lat_2=58.5 +lat_0=45 +lon_0=-126 +x_0=1000000 +y_0=0 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3174, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=42.122774 +lat_2=49.01518 +lat_0=45.568977 +lon_0=-84.455955 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3175, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=42.122774 +lat_2=49.01518 +lat_0=45.568977 +lon_0=-83.248627 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3309, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=clrk66 +datum=NAD27 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3310, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=GRS80 +datum=NAD83 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3311, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3338, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3467, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=55 +lat_2=65 +lat_0=50 +lon_0=-154 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3488, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3513, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=24 +lat_2=31.5 +lat_0=24 +lon_0=-84 +x_0=400000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3577, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=-18 +lat_2=-36 +lat_0=0 +lon_0=132 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3578, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=61.66666666666666 +lat_2=68 +lat_0=59 +lon_0=-132.5 +x_0=500000 +y_0=500000 +ellps=GRS80 +datum=NAD83 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3579, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=61.66666666666666 +lat_2=68 +lat_0=59 +lon_0=-132.5 +x_0=500000 +y_0=500000 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3665, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef aea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=aea +lat_1=27.5 +lat_2=35 +lat_0=18 +lon_0=-100 +x_0=1500000 +y_0=6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ }
+ };
+
+
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AEA_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/aeqd.hpp b/src/boost/geometry/extensions/gis/projections/proj/aeqd.hpp
new file mode 100644
index 0000000..ab4e9aa
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/aeqd.hpp
@@ -0,0 +1,454 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/aasincos.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace aeqd{
+ static const double EPS10 = 1.e-10;
+ static const double TOL = 1.e-14;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ struct par_aeqd
+ {
+ double sinph0;
+ double cosph0;
+ double en[EN_SIZE];
+ double M1;
+ double N1;
+ double Mp;
+ double He;
+ double G;
+ int mode;
+ };
+
+
+
+
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_aeqd_ellipsoid : public base_t_fi<base_aeqd_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_aeqd m_proj_parm;
+
+ inline base_aeqd_ellipsoid(const Parameters& par)
+ : base_t_fi<base_aeqd_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, cosphi, sinphi, rho, s, H, H2, c, Az, t, ct, st, cA, sA;
+
+ coslam = cos(lp_lon);
+ cosphi = cos(lp_lat);
+ sinphi = sin(lp_lat);
+ switch (this->m_proj_parm.mode) {
+ case N_POLE:
+ coslam = - coslam;
+ case S_POLE:
+ xy_x = (rho = fabs(this->m_proj_parm.Mp - pj_mlfn(lp_lat, sinphi, cosphi, this->m_proj_parm.en))) *
+ sin(lp_lon);
+ xy_y = rho * coslam;
+ break;
+ case EQUIT:
+ case OBLIQ:
+ if (fabs(lp_lon) < EPS10 && fabs(lp_lat - this->m_par.phi0) < EPS10) {
+ xy_x = xy_y = 0.;
+ break;
+ }
+ t = atan2(this->m_par.one_es * sinphi + this->m_par.es * this->m_proj_parm.N1 * this->m_proj_parm.sinph0 *
+ sqrt(1. - this->m_par.es * sinphi * sinphi), cosphi);
+ ct = cos(t); st = sin(t);
+ Az = atan2(sin(lp_lon) * ct, this->m_proj_parm.cosph0 * st - this->m_proj_parm.sinph0 * coslam * ct);
+ cA = cos(Az); sA = sin(Az);
+ s = aasin( fabs(sA) < TOL ?
+ (this->m_proj_parm.cosph0 * st - this->m_proj_parm.sinph0 * coslam * ct) / cA :
+ sin(lp_lon) * ct / sA );
+ H = this->m_proj_parm.He * cA;
+ H2 = H * H;
+ c = this->m_proj_parm.N1 * s * (1. + s * s * (- H2 * (1. - H2)/6. +
+ s * ( this->m_proj_parm.G * H * (1. - 2. * H2 * H2) / 8. +
+ s * ((H2 * (4. - 7. * H2) - 3. * this->m_proj_parm.G * this->m_proj_parm.G * (1. - 7. * H2)) /
+ 120. - s * this->m_proj_parm.G * H / 48.))));
+ xy_x = c * sA;
+ xy_y = c * cA;
+ break;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double c, Az, cosAz, A, B, D, E, F, psi, t;
+
+ if ((c = boost::math::hypot(xy_x, xy_y)) < EPS10) {
+ lp_lat = this->m_par.phi0;
+ lp_lon = 0.;
+ return;
+ }
+ if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) {
+ cosAz = cos(Az = atan2(xy_x, xy_y));
+ t = this->m_proj_parm.cosph0 * cosAz;
+ B = this->m_par.es * t / this->m_par.one_es;
+ A = - B * t;
+ B *= 3. * (1. - A) * this->m_proj_parm.sinph0;
+ D = c / this->m_proj_parm.N1;
+ E = D * (1. - D * D * (A * (1. + A) / 6. + B * (1. + 3.*A) * D / 24.));
+ F = 1. - E * E * (A / 2. + B * E / 6.);
+ psi = aasin(this->m_proj_parm.sinph0 * cos(E) + t * sin(E));
+ lp_lon = aasin(sin(Az) * sin(E) / cos(psi));
+ if ((t = fabs(psi)) < EPS10)
+ lp_lat = 0.;
+ else if (fabs(t - HALFPI) < 0.)
+ lp_lat = HALFPI;
+ else
+ lp_lat = atan((1. - this->m_par.es * F * this->m_proj_parm.sinph0 / sin(psi)) * tan(psi) /
+ this->m_par.one_es);
+ } else { /* Polar */
+ lp_lat = pj_inv_mlfn(this->m_proj_parm.mode == N_POLE ? this->m_proj_parm.Mp - c : this->m_proj_parm.Mp + c,
+ this->m_par.es, this->m_proj_parm.en);
+ lp_lon = atan2(xy_x, this->m_proj_parm.mode == N_POLE ? -xy_y : xy_y);
+ }
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_aeqd_guam : public base_t_fi<base_aeqd_guam<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_aeqd m_proj_parm;
+
+ inline base_aeqd_guam(const Parameters& par)
+ : base_t_fi<base_aeqd_guam<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double cosphi, sinphi, t;
+
+ cosphi = cos(lp_lat);
+ sinphi = sin(lp_lat);
+ t = 1. / sqrt(1. - this->m_par.es * sinphi * sinphi);
+ xy_x = lp_lon * cosphi * t;
+ xy_y = pj_mlfn(lp_lat, sinphi, cosphi, this->m_proj_parm.en) - this->m_proj_parm.M1 +
+ .5 * lp_lon * lp_lon * cosphi * sinphi * t;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double x2, t;
+ int i;
+
+ x2 = 0.5 * xy_x * xy_x;
+ lp_lat = this->m_par.phi0;
+ for (i = 0; i < 3; ++i) {
+ t = this->m_par.e * sin(lp_lat);
+ lp_lat = pj_inv_mlfn(this->m_proj_parm.M1 + xy_y -
+ x2 * tan(lp_lat) * (t = sqrt(1. - t * t)), this->m_par.es, this->m_proj_parm.en);
+ }
+ lp_lon = xy_x * t / cos(lp_lat);
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_aeqd_spheroid : public base_t_fi<base_aeqd_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_aeqd m_proj_parm;
+
+ inline base_aeqd_spheroid(const Parameters& par)
+ : base_t_fi<base_aeqd_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, cosphi, sinphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ xy_y = cosphi * coslam;
+ goto oblcon;
+ case OBLIQ:
+ xy_y = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosphi * coslam;
+ oblcon:
+ if (fabs(fabs(xy_y) - 1.) < TOL)
+ if (xy_y < 0.)
+ throw proj_exception();
+ else
+ xy_x = xy_y = 0.;
+ else {
+ xy_y = acos(xy_y);
+ xy_y /= sin(xy_y);
+ xy_x = xy_y * cosphi * sin(lp_lon);
+ xy_y *= (this->m_proj_parm.mode == EQUIT) ? sinphi :
+ this->m_proj_parm.cosph0 * sinphi - this->m_proj_parm.sinph0 * cosphi * coslam;
+ }
+ break;
+ case N_POLE:
+ lp_lat = -lp_lat;
+ coslam = -coslam;
+ case S_POLE:
+ if (fabs(lp_lat - HALFPI) < EPS10) throw proj_exception();;
+ xy_x = (xy_y = (HALFPI + lp_lat)) * sin(lp_lon);
+ xy_y *= coslam;
+ break;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double cosc, c_rh, sinc;
+
+ if ((c_rh = boost::math::hypot(xy_x, xy_y)) > PI) {
+ if (c_rh - EPS10 > PI) throw proj_exception();;
+ c_rh = PI;
+ } else if (c_rh < EPS10) {
+ lp_lat = this->m_par.phi0;
+ lp_lon = 0.;
+ return;
+ }
+ if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) {
+ sinc = sin(c_rh);
+ cosc = cos(c_rh);
+ if (this->m_proj_parm.mode == EQUIT) {
+ lp_lat = aasin(xy_y * sinc / c_rh);
+ xy_x *= sinc;
+ xy_y = cosc * c_rh;
+ } else {
+ lp_lat = aasin(cosc * this->m_proj_parm.sinph0 + xy_y * sinc * this->m_proj_parm.cosph0 /
+ c_rh);
+ xy_y = (cosc - this->m_proj_parm.sinph0 * sin(lp_lat)) * c_rh;
+ xy_x *= sinc * this->m_proj_parm.cosph0;
+ }
+ lp_lon = xy_y == 0. ? 0. : atan2(xy_x, xy_y);
+ } else if (this->m_proj_parm.mode == N_POLE) {
+ lp_lat = HALFPI - c_rh;
+ lp_lon = atan2(xy_x, -xy_y);
+ } else {
+ lp_lat = c_rh - HALFPI;
+ lp_lon = atan2(xy_x, xy_y);
+ }
+ }
+ };
+
+ // Azimuthal Equidistant
+ template <typename Parameters>
+ void setup_aeqd(Parameters& par, par_aeqd& proj_parm)
+ {
+ par.phi0 = pj_param(par.params, "rlat_0").f;
+ if (fabs(fabs(par.phi0) - HALFPI) < EPS10) {
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ proj_parm.sinph0 = par.phi0 < 0. ? -1. : 1.;
+ proj_parm.cosph0 = 0.;
+ } else if (fabs(par.phi0) < EPS10) {
+ proj_parm.mode = EQUIT;
+ proj_parm.sinph0 = 0.;
+ proj_parm.cosph0 = 1.;
+ } else {
+ proj_parm.mode = OBLIQ;
+ proj_parm.sinph0 = sin(par.phi0);
+ proj_parm.cosph0 = cos(par.phi0);
+ }
+ if (! par.es) {
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ } else {
+ pj_enfn(par.es, proj_parm.en);
+ if (pj_param(par.params, "bguam").i) {
+ proj_parm.M1 = pj_mlfn(par.phi0, proj_parm.sinph0, proj_parm.cosph0, proj_parm.en);
+ // par.inv = e_guam_inv;
+ // par.fwd = e_guam_fwd;
+ } else {
+ switch (proj_parm.mode) {
+ case N_POLE:
+ proj_parm.Mp = pj_mlfn(HALFPI, 1., 0., proj_parm.en);
+ break;
+ case S_POLE:
+ proj_parm.Mp = pj_mlfn(-HALFPI, -1., 0., proj_parm.en);
+ break;
+ case EQUIT:
+ case OBLIQ:
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ proj_parm.N1 = 1. / sqrt(1. - par.es * proj_parm.sinph0 * proj_parm.sinph0);
+ proj_parm.G = proj_parm.sinph0 * (proj_parm.He = par.e / sqrt(par.one_es));
+ proj_parm.He *= proj_parm.cosph0;
+ break;
+ }
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+ }
+ }
+
+ }} // namespace detail::aeqd
+ #endif // doxygen
+
+ /*!
+ \brief Azimuthal Equidistant projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ - lat_0 guam
+ \par Example
+ \image html ex_aeqd.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct aeqd_ellipsoid : public detail::aeqd::base_aeqd_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline aeqd_ellipsoid(const Parameters& par) : detail::aeqd::base_aeqd_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Azimuthal Equidistant projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ - lat_0 guam
+ \par Example
+ \image html ex_aeqd.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct aeqd_guam : public detail::aeqd::base_aeqd_guam<Geographic, Cartesian, Parameters>
+ {
+ inline aeqd_guam(const Parameters& par) : detail::aeqd::base_aeqd_guam<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Azimuthal Equidistant projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ - lat_0 guam
+ \par Example
+ \image html ex_aeqd.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct aeqd_spheroid : public detail::aeqd::base_aeqd_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline aeqd_spheroid(const Parameters& par) : detail::aeqd::base_aeqd_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::aeqd::setup_aeqd(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class aeqd_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (! par.es)
+ return new base_v_fi<aeqd_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else if (pj_param(par.params, "bguam").i)
+ return new base_v_fi<aeqd_guam<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<aeqd_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void aeqd_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("aeqd", new aeqd_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/airy.hpp b/src/boost/geometry/extensions/gis/projections/proj/airy.hpp
new file mode 100644
index 0000000..8bbf199
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/airy.hpp
@@ -0,0 +1,217 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace airy{
+ static const double EPS = 1.e-10;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ struct par_airy
+ {
+ double p_halfpi;
+ double sinph0;
+ double cosph0;
+ double Cb;
+ int mode;
+ int no_cut; /* do not cut at hemisphere limit */
+ };
+
+
+
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_airy_spheroid : public base_t_f<base_airy_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_airy m_proj_parm;
+
+ inline base_airy_spheroid(const Parameters& par)
+ : base_t_f<base_airy_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz;
+
+ sinlam = sin(lp_lon);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ case OBLIQ:
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ cosz = cosphi * coslam;
+ if (this->m_proj_parm.mode == OBLIQ)
+ cosz = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosz;
+ if (!this->m_proj_parm.no_cut && cosz < -EPS)
+ throw proj_exception();;
+ if (fabs(s = 1. - cosz) > EPS) {
+ t = 0.5 * (1. + cosz);
+ Krho = -log(t)/s - this->m_proj_parm.Cb / t;
+ } else
+ Krho = 0.5 - this->m_proj_parm.Cb;
+ xy_x = Krho * cosphi * sinlam;
+ if (this->m_proj_parm.mode == OBLIQ)
+ xy_y = Krho * (this->m_proj_parm.cosph0 * sinphi -
+ this->m_proj_parm.sinph0 * cosphi * coslam);
+ else
+ xy_y = Krho * sinphi;
+ break;
+ case S_POLE:
+ case N_POLE:
+ lp_lat = fabs(this->m_proj_parm.p_halfpi - lp_lat);
+ if (!this->m_proj_parm.no_cut && (lp_lat - EPS) > HALFPI)
+ throw proj_exception();;
+ if ((lp_lat *= 0.5) > EPS) {
+ t = tan(lp_lat);
+ Krho = -2.*(log(cos(lp_lat)) / t + t * this->m_proj_parm.Cb);
+ xy_x = Krho * sinlam;
+ xy_y = Krho * coslam;
+ if (this->m_proj_parm.mode == N_POLE)
+ xy_y = -xy_y;
+ } else
+ xy_x = xy_y = 0.;
+ }
+ }
+ };
+
+ // Airy
+ template <typename Parameters>
+ void setup_airy(Parameters& par, par_airy& proj_parm)
+ {
+ double beta;
+ proj_parm.no_cut = pj_param(par.params, "bno_cut").i;
+ beta = 0.5 * (HALFPI - pj_param(par.params, "rlat_b").f);
+ if (fabs(beta) < EPS)
+ proj_parm.Cb = -0.5;
+ else {
+ proj_parm.Cb = 1./tan(beta);
+ proj_parm.Cb *= proj_parm.Cb * log(cos(beta));
+ }
+ if (fabs(fabs(par.phi0) - HALFPI) < EPS)
+ if (par.phi0 < 0.) {
+ proj_parm.p_halfpi = -HALFPI;
+ proj_parm.mode = S_POLE;
+ } else {
+ proj_parm.p_halfpi = HALFPI;
+ proj_parm.mode = N_POLE;
+ }
+ else {
+ if (fabs(par.phi0) < EPS)
+ proj_parm.mode = EQUIT;
+ else {
+ proj_parm.mode = OBLIQ;
+ proj_parm.sinph0 = sin(par.phi0);
+ proj_parm.cosph0 = cos(par.phi0);
+ }
+ }
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::airy
+ #endif // doxygen
+
+ /*!
+ \brief Airy projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ - no_cut lat_b=
+ \par Example
+ \image html ex_airy.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct airy_spheroid : public detail::airy::base_airy_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline airy_spheroid(const Parameters& par) : detail::airy::base_airy_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::airy::setup_airy(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class airy_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<airy_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void airy_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("airy", new airy_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/aitoff.hpp b/src/boost/geometry/extensions/gis/projections/proj/aitoff.hpp
new file mode 100644
index 0000000..8e864c3
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/aitoff.hpp
@@ -0,0 +1,210 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace aitoff{
+
+ struct par_aitoff
+ {
+ double cosphi1;
+ int mode;
+ };
+
+
+
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_aitoff_spheroid : public base_t_f<base_aitoff_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_aitoff m_proj_parm;
+
+ inline base_aitoff_spheroid(const Parameters& par)
+ : base_t_f<base_aitoff_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double c, d;
+
+ if((d = acos(cos(lp_lat) * cos(c = 0.5 * lp_lon)))) {/* basic Aitoff */
+ xy_x = 2. * d * cos(lp_lat) * sin(c) * (xy_y = 1. / sin(d));
+ xy_y *= d * sin(lp_lat);
+ } else
+ xy_x = xy_y = 0.;
+ if (this->m_proj_parm.mode) { /* Winkel Tripel */
+ xy_x = (xy_x + lp_lon * this->m_proj_parm.cosphi1) * 0.5;
+ xy_y = (xy_y + lp_lat) * 0.5;
+ }
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_aitoff& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ // par.inv = 0;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+
+ // Aitoff
+ template <typename Parameters>
+ void setup_aitoff(Parameters& par, par_aitoff& proj_parm)
+ {
+ proj_parm.mode = 0;
+ setup(par, proj_parm);
+ }
+
+ // Winkel Tripel
+ template <typename Parameters>
+ void setup_wintri(Parameters& par, par_aitoff& proj_parm)
+ {
+ proj_parm.mode = 1;
+ if (pj_param(par.params, "tlat_1").i)
+ {
+ if ((proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_1").f)) == 0.)
+ throw proj_exception(-22);
+ }
+ else /* 50d28' or acos(2/pi) */
+ proj_parm.cosphi1 = 0.636619772367581343;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::aitoff
+ #endif // doxygen
+
+ /*!
+ \brief Aitoff projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ \par Example
+ \image html ex_aitoff.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct aitoff_spheroid : public detail::aitoff::base_aitoff_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline aitoff_spheroid(const Parameters& par) : detail::aitoff::base_aitoff_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::aitoff::setup_aitoff(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Winkel Tripel projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - lat_1
+ \par Example
+ \image html ex_wintri.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wintri_spheroid : public detail::aitoff::base_aitoff_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wintri_spheroid(const Parameters& par) : detail::aitoff::base_aitoff_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::aitoff::setup_wintri(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class aitoff_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<aitoff_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wintri_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<wintri_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void aitoff_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("aitoff", new aitoff_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("wintri", new wintri_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AITOFF_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/august.hpp b/src/boost/geometry/extensions/gis/projections/proj/august.hpp
new file mode 100644
index 0000000..ae1877b
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/august.hpp
@@ -0,0 +1,141 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace august{
+ static const double M = 1.333333333333333;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_august_spheroid : public base_t_f<base_august_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_august_spheroid(const Parameters& par)
+ : base_t_f<base_august_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double t, c1, c, x1, x12, y1, y12;
+
+ t = tan(.5 * lp_lat);
+ c1 = sqrt(1. - t * t);
+ c = 1. + c1 * cos(lp_lon *= .5);
+ x1 = sin(lp_lon) * c1 / c;
+ y1 = t / c;
+ xy_x = M * x1 * (3. + (x12 = x1 * x1) - 3. * (y12 = y1 * y1));
+ xy_y = M * y1 * (3. + 3. * x12 - y12);
+ }
+ };
+
+ // August Epicycloidal
+ template <typename Parameters>
+ void setup_august(Parameters& par)
+ {
+ // par.inv = 0;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::august
+ #endif // doxygen
+
+ /*!
+ \brief August Epicycloidal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_august.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct august_spheroid : public detail::august::base_august_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline august_spheroid(const Parameters& par) : detail::august::base_august_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::august::setup_august(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class august_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<august_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void august_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("august", new august_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_AUGUST_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/bacon.hpp b/src/boost/geometry/extensions/gis/projections/proj/bacon.hpp
new file mode 100644
index 0000000..f36d0ec
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/bacon.hpp
@@ -0,0 +1,238 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_BACON_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_BACON_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace bacon{
+ static const double HLFPI2 = 2.46740110027233965467;
+ static const double EPS = 1e-10;
+
+ struct par_bacon
+ {
+ int bacn;
+ int ortl;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_bacon_spheroid : public base_t_f<base_bacon_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_bacon m_proj_parm;
+
+ inline base_bacon_spheroid(const Parameters& par)
+ : base_t_f<base_bacon_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double ax, f;
+
+ xy_y = this->m_proj_parm.bacn ? HALFPI * sin(lp_lat) : lp_lat;
+ if ((ax = fabs(lp_lon)) >= EPS) {
+ if (this->m_proj_parm.ortl && ax >= HALFPI)
+ xy_x = sqrt(HLFPI2 - lp_lat * lp_lat + EPS) + ax - HALFPI;
+ else {
+ f = 0.5 * (HLFPI2 / ax + ax);
+ xy_x = ax - f + sqrt(f * f - xy_y * xy_y);
+ }
+ if (lp_lon < 0.) xy_x = - xy_x;
+ } else
+ xy_x = 0.;
+ }
+ };
+
+ // Apian Globular I
+ template <typename Parameters>
+ void setup_apian(Parameters& par, par_bacon& proj_parm)
+ {
+ proj_parm.bacn = proj_parm.ortl = 0;
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ // Ortelius Oval
+ template <typename Parameters>
+ void setup_ortel(Parameters& par, par_bacon& proj_parm)
+ {
+ proj_parm.bacn = 0;
+ proj_parm.ortl = 1;
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ // Bacon Globular
+ template <typename Parameters>
+ void setup_bacon(Parameters& par, par_bacon& proj_parm)
+ {
+ proj_parm.bacn = 1;
+ proj_parm.ortl = 0;
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::bacon
+ #endif // doxygen
+
+ /*!
+ \brief Apian Globular I projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_apian.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct apian_spheroid : public detail::bacon::base_bacon_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline apian_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::bacon::setup_apian(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Ortelius Oval projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_ortel.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct ortel_spheroid : public detail::bacon::base_bacon_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline ortel_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::bacon::setup_ortel(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Bacon Globular projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_bacon.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct bacon_spheroid : public detail::bacon::base_bacon_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline bacon_spheroid(const Parameters& par) : detail::bacon::base_bacon_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::bacon::setup_bacon(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class apian_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<apian_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class ortel_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<ortel_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class bacon_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<bacon_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void bacon_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("apian", new apian_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("ortel", new ortel_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("bacon", new bacon_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BACON_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/bipc.hpp b/src/boost/geometry/extensions/gis/projections/proj/bipc.hpp
new file mode 100644
index 0000000..3badf22
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/bipc.hpp
@@ -0,0 +1,253 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace bipc{
+ static const double EPS = 1e-10;
+ static const double EPS10 = 1e-10;
+ static const double ONEEPS = 1.000000001;
+ static const int NITER = 10;
+ static const double lamB = -.34894976726250681539;
+ static const double n = .63055844881274687180;
+ static const double F = 1.89724742567461030582;
+ static const double Azab = .81650043674686363166;
+ static const double Azba = 1.82261843856185925133;
+ static const double T = 1.27246578267089012270;
+ static const double rhoc = 1.20709121521568721927;
+ static const double cAzc = .69691523038678375519;
+ static const double sAzc = .71715351331143607555;
+ static const double C45 = .70710678118654752469;
+ static const double S45 = .70710678118654752410;
+ static const double C20 = .93969262078590838411;
+ static const double S20 = -.34202014332566873287;
+ static const double R110 = 1.91986217719376253360;
+ static const double R104 = 1.81514242207410275904;
+
+ struct par_bipc
+ {
+ int noskew;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_bipc_spheroid : public base_t_fi<base_bipc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_bipc m_proj_parm;
+
+ inline base_bipc_spheroid(const Parameters& par)
+ : base_t_fi<base_bipc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double cphi, sphi, tphi, t, al, Az, z, Av, cdlam, sdlam, r;
+ int tag;
+
+ cphi = cos(lp_lat);
+ sphi = sin(lp_lat);
+ cdlam = cos(sdlam = lamB - lp_lon);
+ sdlam = sin(sdlam);
+ if (fabs(fabs(lp_lat) - HALFPI) < EPS10) {
+ Az = lp_lat < 0. ? PI : 0.;
+ tphi = HUGE_VAL;
+ } else {
+ tphi = sphi / cphi;
+ Az = atan2(sdlam , C45 * (tphi - cdlam));
+ }
+ if( (tag = (Az > Azba)) ) {
+ cdlam = cos(sdlam = lp_lon + R110);
+ sdlam = sin(sdlam);
+ z = S20 * sphi + C20 * cphi * cdlam;
+ if (fabs(z) > 1.) {
+ if (fabs(z) > ONEEPS) throw proj_exception();
+ else z = z < 0. ? -1. : 1.;
+ } else
+ z = acos(z);
+ if (tphi != HUGE_VAL)
+ Az = atan2(sdlam, (C20 * tphi - S20 * cdlam));
+ Av = Azab;
+ xy_y = rhoc;
+ } else {
+ z = S45 * (sphi + cphi * cdlam);
+ if (fabs(z) > 1.) {
+ if (fabs(z) > ONEEPS) throw proj_exception();
+ else z = z < 0. ? -1. : 1.;
+ } else
+ z = acos(z);
+ Av = Azba;
+ xy_y = -rhoc;
+ }
+ if (z < 0.) throw proj_exception();;
+ r = F * (t = pow(tan(.5 * z), n));
+ if ((al = .5 * (R104 - z)) < 0.) throw proj_exception();;
+ al = (t + pow(al, n)) / T;
+ if (fabs(al) > 1.) {
+ if (fabs(al) > ONEEPS) throw proj_exception();
+ else al = al < 0. ? -1. : 1.;
+ } else
+ al = acos(al);
+ if (fabs(t = n * (Av - Az)) < al)
+ r /= cos(al + (tag ? t : -t));
+ xy_x = r * sin(t);
+ xy_y += (tag ? -r : r) * cos(t);
+ if (this->m_proj_parm.noskew) {
+ t = xy_x;
+ xy_x = -xy_x * cAzc - xy_y * sAzc;
+ xy_y = -xy_y * cAzc + t * sAzc;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double t, r, rp, rl, al, z, fAz, Az, s, c, Av;
+ int neg, i;
+
+ if (this->m_proj_parm.noskew) {
+ t = xy_x;
+ xy_x = -xy_x * cAzc + xy_y * sAzc;
+ xy_y = -xy_y * cAzc - t * sAzc;
+ }
+ if( (neg = (xy_x < 0.)) ) {
+ xy_y = rhoc - xy_y;
+ s = S20;
+ c = C20;
+ Av = Azab;
+ } else {
+ xy_y += rhoc;
+ s = S45;
+ c = C45;
+ Av = Azba;
+ }
+ rl = rp = r = boost::math::hypot(xy_x, xy_y);
+ fAz = fabs(Az = atan2(xy_x, xy_y));
+ for (i = NITER; i ; --i) {
+ z = 2. * atan(pow(r / F,1 / n));
+ al = acos((pow(tan(.5 * z), n) +
+ pow(tan(.5 * (R104 - z)), n)) / T);
+ if (fAz < al)
+ r = rp * cos(al + (neg ? Az : -Az));
+ if (fabs(rl - r) < EPS)
+ break;
+ rl = r;
+ }
+ if (! i) throw proj_exception();;
+ Az = Av - Az / n;
+ lp_lat = asin(s * cos(z) + c * sin(z) * cos(Az));
+ lp_lon = atan2(sin(Az), c / tan(z) - s * cos(Az));
+ if (neg)
+ lp_lon -= R110;
+ else
+ lp_lon = lamB - lp_lon;
+ }
+ };
+
+ // Bipolar conic of western hemisphere
+ template <typename Parameters>
+ void setup_bipc(Parameters& par, par_bipc& proj_parm)
+ {
+ proj_parm.noskew = pj_param(par.params, "bns").i;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::bipc
+ #endif // doxygen
+
+ /*!
+ \brief Bipolar conic of western hemisphere projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ \par Example
+ \image html ex_bipc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct bipc_spheroid : public detail::bipc::base_bipc_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline bipc_spheroid(const Parameters& par) : detail::bipc::base_bipc_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::bipc::setup_bipc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class bipc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<bipc_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void bipc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("bipc", new bipc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BIPC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/boggs.hpp b/src/boost/geometry/extensions/gis/projections/proj/boggs.hpp
new file mode 100644
index 0000000..e4276e7
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/boggs.hpp
@@ -0,0 +1,154 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace boggs{
+ static const int NITER = 20;
+ static const double EPS = 1e-7;
+ static const double ONETOL = 1.000001;
+ static const double FXC = 2.00276;
+ static const double FXC2 = 1.11072;
+ static const double FYC = 0.49931;
+ static const double FYC2 = 1.41421356237309504880;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_boggs_spheroid : public base_t_f<base_boggs_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_boggs_spheroid(const Parameters& par)
+ : base_t_f<base_boggs_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double theta, th1, c;
+ int i;
+
+ theta = lp_lat;
+ if (fabs(fabs(lp_lat) - HALFPI) < EPS)
+ xy_x = 0.;
+ else {
+ c = sin(theta) * PI;
+ for (i = NITER; i; --i) {
+ theta -= th1 = (theta + sin(theta) - c) /
+ (1. + cos(theta));
+ if (fabs(th1) < EPS) break;
+ }
+ theta *= 0.5;
+ xy_x = FXC * lp_lon / (1. / cos(lp_lat) + FXC2 / cos(theta));
+ }
+ xy_y = FYC * (lp_lat + FYC2 * sin(theta));
+ }
+ };
+
+ // Boggs Eumorphic
+ template <typename Parameters>
+ void setup_boggs(Parameters& par)
+ {
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::boggs
+ #endif // doxygen
+
+ /*!
+ \brief Boggs Eumorphic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - no inverse
+ - Spheroid
+ \par Example
+ \image html ex_boggs.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct boggs_spheroid : public detail::boggs::base_boggs_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline boggs_spheroid(const Parameters& par) : detail::boggs::base_boggs_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::boggs::setup_boggs(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class boggs_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<boggs_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void boggs_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("boggs", new boggs_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BOGGS_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/bonne.hpp b/src/boost/geometry/extensions/gis/projections/proj/bonne.hpp
new file mode 100644
index 0000000..853ae13
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/bonne.hpp
@@ -0,0 +1,246 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace bonne{
+ static const double EPS10 = 1e-10;
+
+ struct par_bonne
+ {
+ double phi1;
+ double cphi1;
+ double am1;
+ double m1;
+ double en[EN_SIZE];
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_bonne_ellipsoid : public base_t_fi<base_bonne_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_bonne m_proj_parm;
+
+ inline base_bonne_ellipsoid(const Parameters& par)
+ : base_t_fi<base_bonne_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double rh, E, c;
+
+ rh = this->m_proj_parm.am1 + this->m_proj_parm.m1 - pj_mlfn(lp_lat, E = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en);
+ E = c * lp_lon / (rh * sqrt(1. - this->m_par.es * E * E));
+ xy_x = rh * sin(E);
+ xy_y = this->m_proj_parm.am1 - rh * cos(E);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double s, rh;
+
+ rh = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.am1 - xy_y);
+ lp_lat = pj_inv_mlfn(this->m_proj_parm.am1 + this->m_proj_parm.m1 - rh, this->m_par.es, this->m_proj_parm.en);
+ if ((s = fabs(lp_lat)) < HALFPI) {
+ s = sin(lp_lat);
+ lp_lon = rh * atan2(xy_x, xy_y) *
+ sqrt(1. - this->m_par.es * s * s) / cos(lp_lat);
+ } else if (fabs(s - HALFPI) <= EPS10)
+ lp_lon = 0.;
+ else throw proj_exception();;
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_bonne_spheroid : public base_t_fi<base_bonne_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_bonne m_proj_parm;
+
+ inline base_bonne_spheroid(const Parameters& par)
+ : base_t_fi<base_bonne_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double E, rh;
+
+ rh = this->m_proj_parm.cphi1 + this->m_proj_parm.phi1 - lp_lat;
+ if (fabs(rh) > EPS10) {
+ xy_x = rh * sin(E = lp_lon * cos(lp_lat) / rh);
+ xy_y = this->m_proj_parm.cphi1 - rh * cos(E);
+ } else
+ xy_x = xy_y = 0.;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rh;
+
+ rh = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.cphi1 - xy_y);
+ lp_lat = this->m_proj_parm.cphi1 + this->m_proj_parm.phi1 - rh;
+ if (fabs(lp_lat) > HALFPI) throw proj_exception();;
+ if (fabs(fabs(lp_lat) - HALFPI) <= EPS10)
+ lp_lon = 0.;
+ else
+ lp_lon = rh * atan2(xy_x, xy_y) / cos(lp_lat);
+ }
+ };
+
+ // Bonne (Werner lat_1=90)
+ template <typename Parameters>
+ void setup_bonne(Parameters& par, par_bonne& proj_parm)
+ {
+ double c;
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ if (fabs(proj_parm.phi1) < EPS10) throw proj_exception(-23);
+ if (par.es) {
+ pj_enfn(par.es, proj_parm.en);
+ proj_parm.m1 = pj_mlfn(proj_parm.phi1, proj_parm.am1 = sin(proj_parm.phi1),
+ c = cos(proj_parm.phi1), proj_parm.en);
+ proj_parm.am1 = c / (sqrt(1. - par.es * proj_parm.am1 * proj_parm.am1) * proj_parm.am1);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ if (fabs(proj_parm.phi1) + EPS10 >= HALFPI)
+ proj_parm.cphi1 = 0.;
+ else
+ proj_parm.cphi1 = 1. / tan(proj_parm.phi1);
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+ }} // namespace detail::bonne
+ #endif // doxygen
+
+ /*!
+ \brief Bonne (Werner lat_1=90) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ - lat_1=
+ \par Example
+ \image html ex_bonne.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct bonne_ellipsoid : public detail::bonne::base_bonne_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline bonne_ellipsoid(const Parameters& par) : detail::bonne::base_bonne_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::bonne::setup_bonne(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Bonne (Werner lat_1=90) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ - lat_1=
+ \par Example
+ \image html ex_bonne.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct bonne_spheroid : public detail::bonne::base_bonne_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline bonne_spheroid(const Parameters& par) : detail::bonne::base_bonne_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::bonne::setup_bonne(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class bonne_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<bonne_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<bonne_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void bonne_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("bonne", new bonne_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_BONNE_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/cass.hpp b/src/boost/geometry/extensions/gis/projections/proj/cass.hpp
new file mode 100644
index 0000000..1d1603c
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/cass.hpp
@@ -0,0 +1,465 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+#include <boost/geometry/extensions/gis/projections/epsg_traits.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace cass{
+ static const double EPS10 = 1e-10;
+ static const double C1 = .16666666666666666666;
+ static const double C2 = .00833333333333333333;
+ static const double C3 = .04166666666666666666;
+ static const double C4 = .33333333333333333333;
+ static const double C5 = .06666666666666666666;
+
+ struct par_cass
+ {
+ double m0;
+ double n;
+ double t;
+ double a1;
+ double c;
+ double r;
+ double dd;
+ double d2;
+ double a2;
+ double tn;
+ double en[EN_SIZE];
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_cass_ellipsoid : public base_t_fi<base_cass_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ mutable par_cass m_proj_parm;
+
+ inline base_cass_ellipsoid(const Parameters& par)
+ : base_t_fi<base_cass_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_y = pj_mlfn(lp_lat, this->m_proj_parm.n = sin(lp_lat), this->m_proj_parm.c = cos(lp_lat), this->m_proj_parm.en);
+ this->m_proj_parm.n = 1./sqrt(1. - this->m_par.es * this->m_proj_parm.n * this->m_proj_parm.n);
+ this->m_proj_parm.tn = tan(lp_lat); this->m_proj_parm.t = this->m_proj_parm.tn * this->m_proj_parm.tn;
+ this->m_proj_parm.a1 = lp_lon * this->m_proj_parm.c;
+ this->m_proj_parm.c *= this->m_par.es * this->m_proj_parm.c / (1 - this->m_par.es);
+ this->m_proj_parm.a2 = this->m_proj_parm.a1 * this->m_proj_parm.a1;
+ xy_x = this->m_proj_parm.n * this->m_proj_parm.a1 * (1. - this->m_proj_parm.a2 * this->m_proj_parm.t *
+ (C1 - (8. - this->m_proj_parm.t + 8. * this->m_proj_parm.c) * this->m_proj_parm.a2 * C2));
+ xy_y -= this->m_proj_parm.m0 - this->m_proj_parm.n * this->m_proj_parm.tn * this->m_proj_parm.a2 *
+ (.5 + (5. - this->m_proj_parm.t + 6. * this->m_proj_parm.c) * this->m_proj_parm.a2 * C3);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double ph1;
+
+ ph1 = pj_inv_mlfn(this->m_proj_parm.m0 + xy_y, this->m_par.es, this->m_proj_parm.en);
+ this->m_proj_parm.tn = tan(ph1); this->m_proj_parm.t = this->m_proj_parm.tn * this->m_proj_parm.tn;
+ this->m_proj_parm.n = sin(ph1);
+ this->m_proj_parm.r = 1. / (1. - this->m_par.es * this->m_proj_parm.n * this->m_proj_parm.n);
+ this->m_proj_parm.n = sqrt(this->m_proj_parm.r);
+ this->m_proj_parm.r *= (1. - this->m_par.es) * this->m_proj_parm.n;
+ this->m_proj_parm.dd = xy_x / this->m_proj_parm.n;
+ this->m_proj_parm.d2 = this->m_proj_parm.dd * this->m_proj_parm.dd;
+ lp_lat = ph1 - (this->m_proj_parm.n * this->m_proj_parm.tn / this->m_proj_parm.r) * this->m_proj_parm.d2 *
+ (.5 - (1. + 3. * this->m_proj_parm.t) * this->m_proj_parm.d2 * C3);
+ lp_lon = this->m_proj_parm.dd * (1. + this->m_proj_parm.t * this->m_proj_parm.d2 *
+ (-C4 + (1. + 3. * this->m_proj_parm.t) * this->m_proj_parm.d2 * C5)) / cos(ph1);
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_cass_spheroid : public base_t_fi<base_cass_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ mutable par_cass m_proj_parm;
+
+ inline base_cass_spheroid(const Parameters& par)
+ : base_t_fi<base_cass_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = asin(cos(lp_lat) * sin(lp_lon));
+ xy_y = atan2(tan(lp_lat) , cos(lp_lon)) - this->m_par.phi0;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = asin(sin(this->m_proj_parm.dd = xy_y + this->m_par.phi0) * cos(xy_x));
+ lp_lon = atan2(tan(xy_x), cos(this->m_proj_parm.dd));
+ }
+ };
+
+ // Cassini
+ template <typename Parameters>
+ void setup_cass(Parameters& par, par_cass& proj_parm)
+ {
+ if (par.es) {
+ pj_enfn(par.es, proj_parm.en);
+ proj_parm.m0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+ }} // namespace detail::cass
+ #endif // doxygen
+
+ /*!
+ \brief Cassini projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_cass.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct cass_ellipsoid : public detail::cass::base_cass_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline cass_ellipsoid(const Parameters& par) : detail::cass::base_cass_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::cass::setup_cass(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Cassini projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_cass.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct cass_spheroid : public detail::cass::base_cass_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline cass_spheroid(const Parameters& par) : detail::cass::base_cass_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::cass::setup_cass(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class cass_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<cass_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<cass_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void cass_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("cass", new cass_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ // Create EPSG specializations
+ // (Proof of Concept, only for some)
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2066, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=11.25217861111111 +lon_0=-60.68600888888889 +x_0=37718.66159325 +y_0=36209.91512952 +a=6378293.645208759 +b=6356617.987679838 +to_meter=0.201166195164";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2099, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=25.38236111111111 +lon_0=50.76138888888889 +x_0=100000 +y_0=100000 +ellps=helmert +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2314, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=10.44166666666667 +lon_0=-61.33333333333334 +x_0=86501.46392052001 +y_0=65379.0134283 +a=6378293.645208759 +b=6356617.987679838 +to_meter=0.3047972654";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3068, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=52.41864827777778 +lon_0=13.62720366666667 +x_0=40000 +y_0=10000 +ellps=bessel +datum=potsdam +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3140, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=-18 +lon_0=178 +x_0=109435.392 +y_0=141622.272 +a=6378306.3696 +b=6356571.996 +towgs84=51,391,-36,0,0,0,0 +to_meter=0.201168";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3366, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=22.31213333333334 +lon_0=114.1785555555556 +x_0=40243.57775604237 +y_0=19069.93351512578 +a=6378293.645208759 +b=6356617.987679838 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3377, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=2.121679744444445 +lon_0=103.4279362361111 +x_0=-14810.562 +y_0=8758.32 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3378, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=2.682347636111111 +lon_0=101.9749050416667 +x_0=3673.785 +y_0=-4240.573 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3379, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=3.769388088888889 +lon_0=102.3682989833333 +x_0=-7368.228 +y_0=6485.858 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3380, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=3.68464905 +lon_0=101.3891079138889 +x_0=-34836.161 +y_0=56464.049 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3381, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=4.9762852 +lon_0=103.070275625 +x_0=19594.245 +y_0=3371.895 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3382, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=5.421517541666667 +lon_0=100.3443769638889 +x_0=-23.414 +y_0=62.283 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3383, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=5.964672713888889 +lon_0=100.6363711111111 +x_0=0 +y_0=0 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3384, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=4.859063022222222 +lon_0=100.8154105861111 +x_0=-1.769 +y_0=133454.779 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3385, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=5.972543658333334 +lon_0=102.2952416694444 +x_0=13227.851 +y_0=8739.894 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3407, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=22.31213333333334 +lon_0=114.1785555555556 +x_0=40243.57775604237 +y_0=19069.93351512578 +a=6378293.645208759 +b=6356617.987679838 +to_meter=0.3047972654";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<24500, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=1.287646666666667 +lon_0=103.8530022222222 +x_0=30000 +y_0=30000 +a=6377304.063 +b=6356103.038993155 +towgs84=-11,851,5,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<28191, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<28193, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=1126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<30200, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef cass_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=cass +lat_0=10.44166666666667 +lon_0=-61.33333333333334 +x_0=86501.46392051999 +y_0=65379.0134283 +a=6378293.645208759 +b=6356617.987679838 +to_meter=0.201166195164";
+ }
+ };
+
+
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/cc.hpp b/src/boost/geometry/extensions/gis/projections/proj/cc.hpp
new file mode 100644
index 0000000..0945297
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/cc.hpp
@@ -0,0 +1,145 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace cc{
+ static const double EPS10 = 1.e-10;
+
+ struct par_cc
+ {
+ double ap;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_cc_spheroid : public base_t_fi<base_cc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_cc m_proj_parm;
+
+ inline base_cc_spheroid(const Parameters& par)
+ : base_t_fi<base_cc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) throw proj_exception();;
+ xy_x = lp_lon;
+ xy_y = tan(lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = atan(xy_y);
+ lp_lon = xy_x;
+ }
+ };
+
+ // Central Cylindrical
+ template <typename Parameters>
+ void setup_cc(Parameters& par, par_cc& proj_parm)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::cc
+ #endif // doxygen
+
+ /*!
+ \brief Central Cylindrical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_cc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct cc_spheroid : public detail::cc::base_cc_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline cc_spheroid(const Parameters& par) : detail::cc::base_cc_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::cc::setup_cc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class cc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<cc_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void cc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("cc", new cc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/cea.hpp b/src/boost/geometry/extensions/gis/projections/proj/cea.hpp
new file mode 100644
index 0000000..cd0b6dc
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/cea.hpp
@@ -0,0 +1,224 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_auth.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace cea{
+ static const double EPS = 1e-10;
+
+ struct par_cea
+ {
+ double qp;
+ double apa[APA_SIZE];
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_cea_ellipsoid : public base_t_fi<base_cea_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_cea m_proj_parm;
+
+ inline base_cea_ellipsoid(const Parameters& par)
+ : base_t_fi<base_cea_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = this->m_par.k0 * lp_lon;
+ xy_y = .5 * pj_qsfn(sin(lp_lat), this->m_par.e, this->m_par.one_es) / this->m_par.k0;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = pj_authlat(asin( 2. * xy_y * this->m_par.k0 / this->m_proj_parm.qp), this->m_proj_parm.apa);
+ lp_lon = xy_x / this->m_par.k0;
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_cea_spheroid : public base_t_fi<base_cea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_cea m_proj_parm;
+
+ inline base_cea_spheroid(const Parameters& par)
+ : base_t_fi<base_cea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = this->m_par.k0 * lp_lon;
+ xy_y = sin(lp_lat) / this->m_par.k0;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double t;
+
+ if ((t = fabs(xy_y *= this->m_par.k0)) - EPS <= 1.) {
+ if (t >= 1.)
+ lp_lat = xy_y < 0. ? -HALFPI : HALFPI;
+ else
+ lp_lat = asin(xy_y);
+ lp_lon = xy_x / this->m_par.k0;
+ } else throw proj_exception();;
+ }
+ };
+
+ // Equal Area Cylindrical
+ template <typename Parameters>
+ void setup_cea(Parameters& par, par_cea& proj_parm)
+ {
+ double t;
+ if (pj_param(par.params, "tlat_ts").i &&
+ (par.k0 = cos(t = pj_param(par.params, "rlat_ts").f)) < 0.) throw proj_exception(-24);
+ else
+ t = 0.;
+ if (par.es) {
+ t = sin(t);
+ par.k0 /= sqrt(1. - par.es * t * t);
+ par.e = sqrt(par.es);
+ pj_authset(par.es, proj_parm.apa);
+ proj_parm.qp = pj_qsfn(1., par.e, par.one_es);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+ }} // namespace detail::cea
+ #endif // doxygen
+
+ /*!
+ \brief Equal Area Cylindrical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ - lat_ts=
+ \par Example
+ \image html ex_cea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct cea_ellipsoid : public detail::cea::base_cea_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline cea_ellipsoid(const Parameters& par) : detail::cea::base_cea_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::cea::setup_cea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Equal Area Cylindrical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ - lat_ts=
+ \par Example
+ \image html ex_cea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct cea_spheroid : public detail::cea::base_cea_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline cea_spheroid(const Parameters& par) : detail::cea::base_cea_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::cea::setup_cea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class cea_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<cea_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<cea_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void cea_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("cea", new cea_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/chamb.hpp b/src/boost/geometry/extensions/gis/projections/proj/chamb.hpp
new file mode 100644
index 0000000..e9f3977
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/chamb.hpp
@@ -0,0 +1,242 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <cstdio>
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/aasincos.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace chamb{
+ static const double THIRD = 0.333333333333333333;
+ static const double TOL = 1e-9;
+
+ struct VECT { double r, Az; };
+ struct CXY { double x, y; }; // x/y for chamb
+
+ struct par_chamb
+ {
+ struct { /* control point data */
+ double phi, lam;
+ double cosphi, sinphi;
+ VECT v;
+ CXY p;
+ double Az;
+ } c[3];
+ CXY p;
+ double beta_0, beta_1, beta_2;
+ };
+ inline VECT /* distance and azimuth from point 1 to point 2 */
+ vect(double dphi, double c1, double s1, double c2, double s2, double dlam) {
+ VECT v;
+ double cdl, dp, dl;
+
+ cdl = cos(dlam);
+ if (fabs(dphi) > 1. || fabs(dlam) > 1.)
+ v.r = aacos(s1 * s2 + c1 * c2 * cdl);
+ else { /* more accurate for smaller distances */
+ dp = sin(.5 * dphi);
+ dl = sin(.5 * dlam);
+ v.r = 2. * aasin(sqrt(dp * dp + c1 * c2 * dl * dl));
+ }
+ if (fabs(v.r) > TOL)
+ v.Az = atan2(c2 * sin(dlam), c1 * s2 - s1 * c2 * cdl);
+ else
+ v.r = v.Az = 0.;
+ return v;
+ }
+ inline double /* law of cosines */
+ lc(double b,double c,double a) {
+ return aacos(.5 * (b * b + c * c - a * a) / (b * c));
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_chamb_spheroid : public base_t_f<base_chamb_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_chamb m_proj_parm;
+
+ inline base_chamb_spheroid(const Parameters& par)
+ : base_t_f<base_chamb_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double sinphi, cosphi, a;
+ VECT v[3];
+ int i, j;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ for (i = 0; i < 3; ++i) { /* dist/azimiths from control */
+ v[i] = vect(lp_lat - this->m_proj_parm.c[i].phi, this->m_proj_parm.c[i].cosphi, this->m_proj_parm.c[i].sinphi,
+ cosphi, sinphi, lp_lon - this->m_proj_parm.c[i].lam);
+ if ( ! v[i].r)
+ break;
+ v[i].Az = adjlon(v[i].Az - this->m_proj_parm.c[i].v.Az);
+ }
+ if (i < 3) /* current point at control point */
+ { xy_x = this->m_proj_parm.c[i].p.x; xy_y = this->m_proj_parm.c[i].p.y; }
+ else { /* point mean of intersepts */
+ { xy_x = this->m_proj_parm.p.x; xy_y = this->m_proj_parm.p.y; }
+ for (i = 0; i < 3; ++i) {
+ j = i == 2 ? 0 : i + 1;
+ a = lc(this->m_proj_parm.c[i].v.r, v[i].r, v[j].r);
+ if (v[i].Az < 0.)
+ a = -a;
+ if (! i) { /* coord comp unique to each arc */
+ xy_x += v[i].r * cos(a);
+ xy_y -= v[i].r * sin(a);
+ } else if (i == 1) {
+ a = this->m_proj_parm.beta_1 - a;
+ xy_x -= v[i].r * cos(a);
+ xy_y -= v[i].r * sin(a);
+ } else {
+ a = this->m_proj_parm.beta_2 - a;
+ xy_x += v[i].r * cos(a);
+ xy_y += v[i].r * sin(a);
+ }
+ }
+ xy_x *= THIRD; /* mean of arc intercepts */
+ xy_y *= THIRD;
+ }
+ }
+ };
+
+ // Chamberlin Trimetric
+ template <typename Parameters>
+ void setup_chamb(Parameters& par, par_chamb& proj_parm)
+ {
+ int i, j;
+ char line[10];
+ for (i = 0;
+ i < 3;
+ ++i) { /* get control point locations */
+ (void)sprintf(line, "rlat_%d", i+1);
+ proj_parm.c[i].phi = pj_param(par.params, line).f;
+ (void)sprintf(line, "rlon_%d", i+1);
+ proj_parm.c[i].lam = pj_param(par.params, line).f;
+ proj_parm.c[i].lam = adjlon(proj_parm.c[i].lam - par.lam0);
+ proj_parm.c[i].cosphi = cos(proj_parm.c[i].phi);
+ proj_parm.c[i].sinphi = sin(proj_parm.c[i].phi);
+ }
+ for (i = 0;
+ i < 3;
+ ++i) { /* inter ctl pt. distances and azimuths */
+ j = i == 2 ? 0 : i + 1;
+ proj_parm.c[i].v = vect(proj_parm.c[j].phi - proj_parm.c[i].phi, proj_parm.c[i].cosphi, proj_parm.c[i].sinphi,
+ proj_parm.c[j].cosphi, proj_parm.c[j].sinphi, proj_parm.c[j].lam - proj_parm.c[i].lam);
+ if (! proj_parm.c[i].v.r) throw proj_exception(-25);
+ /* co-linearity problem ignored for now */
+ }
+ proj_parm.beta_0 = lc(proj_parm.c[0].v.r, proj_parm.c[2].v.r, proj_parm.c[1].v.r);
+ proj_parm.beta_1 = lc(proj_parm.c[0].v.r, proj_parm.c[1].v.r, proj_parm.c[2].v.r);
+ proj_parm.beta_2 = PI - proj_parm.beta_0;
+ proj_parm.p.y = 2. * (proj_parm.c[0].p.y = proj_parm.c[1].p.y = proj_parm.c[2].v.r * sin(proj_parm.beta_0));
+ proj_parm.c[2].p.y = 0.;
+ proj_parm.c[0].p.x = - (proj_parm.c[1].p.x = 0.5 * proj_parm.c[0].v.r);
+ proj_parm.p.x = proj_parm.c[2].p.x = proj_parm.c[0].p.x + proj_parm.c[2].v.r * cos(proj_parm.beta_0);
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::chamb
+ #endif // doxygen
+
+ /*!
+ \brief Chamberlin Trimetric projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ - lat_1= lon_1= lat_2= lon_2= lat_3= lon_3=
+ \par Example
+ \image html ex_chamb.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct chamb_spheroid : public detail::chamb::base_chamb_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline chamb_spheroid(const Parameters& par) : detail::chamb::base_chamb_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::chamb::setup_chamb(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class chamb_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<chamb_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void chamb_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("chamb", new chamb_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CHAMB_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/collg.hpp b/src/boost/geometry/extensions/gis/projections/proj/collg.hpp
new file mode 100644
index 0000000..048e1ec
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/collg.hpp
@@ -0,0 +1,152 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace collg{
+ static const double FXC = 1.12837916709551257390;
+ static const double FYC = 1.77245385090551602729;
+ static const double ONEEPS = 1.0000001;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_collg_spheroid : public base_t_fi<base_collg_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_collg_spheroid(const Parameters& par)
+ : base_t_fi<base_collg_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if ((xy_y = 1. - sin(lp_lat)) <= 0.)
+ xy_y = 0.;
+ else
+ xy_y = sqrt(xy_y);
+ xy_x = FXC * lp_lon * xy_y;
+ xy_y = FYC * (1. - xy_y);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / FYC - 1.;
+ if (fabs(lp_lat = 1. - lp_lat * lp_lat) < 1.)
+ lp_lat = asin(lp_lat);
+ else if (fabs(lp_lat) > ONEEPS) throw proj_exception();
+ else lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ if ((lp_lon = 1. - sin(lp_lat)) <= 0.)
+ lp_lon = 0.;
+ else
+ lp_lon = xy_x / (FXC * sqrt(lp_lon));
+ }
+ };
+
+ // Collignon
+ template <typename Parameters>
+ void setup_collg(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::collg
+ #endif // doxygen
+
+ /*!
+ \brief Collignon projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_collg.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct collg_spheroid : public detail::collg::base_collg_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline collg_spheroid(const Parameters& par) : detail::collg::base_collg_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::collg::setup_collg(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class collg_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<collg_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void collg_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("collg", new collg_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_COLLG_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/crast.hpp b/src/boost/geometry/extensions/gis/projections/proj/crast.hpp
new file mode 100644
index 0000000..360fd46
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/crast.hpp
@@ -0,0 +1,144 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace crast{
+ static const double XM = 0.97720502380583984317;
+ static const double RXM = 1.02332670794648848847;
+ static const double YM = 3.06998012383946546542;
+ static const double RYM = 0.32573500793527994772;
+ static const double THIRD = 0.333333333333333333;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_crast_spheroid : public base_t_fi<base_crast_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_crast_spheroid(const Parameters& par)
+ : base_t_fi<base_crast_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat *= THIRD;
+ xy_x = XM * lp_lon * (2. * cos(lp_lat + lp_lat) - 1.);
+ xy_y = YM * sin(lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = 3. * asin(xy_y * RYM);
+ lp_lon = xy_x * RXM / (2. * cos((lp_lat + lp_lat) * THIRD) - 1);
+ }
+ };
+
+ // Craster Parabolic (Putnins P4)
+ template <typename Parameters>
+ void setup_crast(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::crast
+ #endif // doxygen
+
+ /*!
+ \brief Craster Parabolic (Putnins P4) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_crast.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct crast_spheroid : public detail::crast::base_crast_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline crast_spheroid(const Parameters& par) : detail::crast::base_crast_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::crast::setup_crast(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class crast_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<crast_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void crast_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("crast", new crast_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_CRAST_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/denoy.hpp b/src/boost/geometry/extensions/gis/projections/proj/denoy.hpp
new file mode 100644
index 0000000..5d696f8
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/denoy.hpp
@@ -0,0 +1,140 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace denoy{
+ static const double C0 = 0.95;
+ static const double C1 = -.08333333333333333333;
+ static const double C3 = .00166666666666666666;
+ static const double D1 = 0.9;
+ static const double D5 = 0.03;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_denoy_spheroid : public base_t_f<base_denoy_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_denoy_spheroid(const Parameters& par)
+ : base_t_f<base_denoy_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_y = lp_lat;
+ xy_x = lp_lon;
+ lp_lon = fabs(lp_lon);
+ xy_x *= cos((C0 + lp_lon * (C1 + lp_lon * lp_lon * C3)) *
+ (lp_lat * (D1 + D5 * lp_lat * lp_lat * lp_lat * lp_lat)));
+ }
+ };
+
+ // Denoyer Semi-Elliptical
+ template <typename Parameters>
+ void setup_denoy(Parameters& par)
+ {
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::denoy
+ #endif // doxygen
+
+ /*!
+ \brief Denoyer Semi-Elliptical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - no inverse
+ - Spheroid
+ \par Example
+ \image html ex_denoy.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct denoy_spheroid : public detail::denoy::base_denoy_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline denoy_spheroid(const Parameters& par) : detail::denoy::base_denoy_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::denoy::setup_denoy(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class denoy_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<denoy_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void denoy_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("denoy", new denoy_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_DENOY_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/eck1.hpp b/src/boost/geometry/extensions/gis/projections/proj/eck1.hpp
new file mode 100644
index 0000000..91644ef
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/eck1.hpp
@@ -0,0 +1,140 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck1{
+ static const double FC = .92131773192356127802;
+ static const double RP = .31830988618379067154;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_eck1_spheroid : public base_t_fi<base_eck1_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_eck1_spheroid(const Parameters& par)
+ : base_t_fi<base_eck1_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = FC * lp_lon * (1. - RP * fabs(lp_lat));
+ xy_y = FC * lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / FC;
+ lp_lon = xy_x / (FC * (1. - RP * fabs(lp_lat)));
+ }
+ };
+
+ // Eckert I
+ template <typename Parameters>
+ void setup_eck1(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::eck1
+ #endif // doxygen
+
+ /*!
+ \brief Eckert I projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck1.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct eck1_spheroid : public detail::eck1::base_eck1_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline eck1_spheroid(const Parameters& par) : detail::eck1::base_eck1_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eck1::setup_eck1(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class eck1_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck1_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void eck1_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("eck1", new eck1_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK1_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/eck2.hpp b/src/boost/geometry/extensions/gis/projections/proj/eck2.hpp
new file mode 100644
index 0000000..4070b33
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/eck2.hpp
@@ -0,0 +1,151 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck2{
+ static const double FXC = 0.46065886596178063902;
+ static const double FYC = 1.44720250911653531871;
+ static const double C13 = 0.33333333333333333333;
+ static const double ONEEPS = 1.0000001;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_eck2_spheroid : public base_t_fi<base_eck2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_eck2_spheroid(const Parameters& par)
+ : base_t_fi<base_eck2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = FXC * lp_lon * (xy_y = sqrt(4. - 3. * sin(fabs(lp_lat))));
+ xy_y = FYC * (2. - xy_y);
+ if ( lp_lat < 0.) xy_y = -xy_y;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lon = xy_x / (FXC * ( lp_lat = 2. - fabs(xy_y) / FYC) );
+ lp_lat = (4. - lp_lat * lp_lat) * C13;
+ if (fabs(lp_lat) >= 1.) {
+ if (fabs(lp_lat) > ONEEPS) throw proj_exception();
+ else
+ lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ } else
+ lp_lat = asin(lp_lat);
+ if (xy_y < 0)
+ lp_lat = -lp_lat;
+ }
+ };
+
+ // Eckert II
+ template <typename Parameters>
+ void setup_eck2(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::eck2
+ #endif // doxygen
+
+ /*!
+ \brief Eckert II projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck2.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct eck2_spheroid : public detail::eck2::base_eck2_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline eck2_spheroid(const Parameters& par) : detail::eck2::base_eck2_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eck2::setup_eck2(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class eck2_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck2_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void eck2_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("eck2", new eck2_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK2_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/eck3.hpp b/src/boost/geometry/extensions/gis/projections/proj/eck3.hpp
new file mode 100644
index 0000000..697a3e7
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/eck3.hpp
@@ -0,0 +1,286 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck3{
+
+ struct par_eck3
+ {
+ double C_x, C_y, A, B;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_eck3_spheroid : public base_t_fi<base_eck3_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_eck3 m_proj_parm;
+
+ inline base_eck3_spheroid(const Parameters& par)
+ : base_t_fi<base_eck3_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_y = this->m_proj_parm.C_y * lp_lat;
+ xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.A + asqrt(1. - this->m_proj_parm.B * lp_lat * lp_lat));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / this->m_proj_parm.C_y;
+ lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.A + asqrt(1. - this->m_proj_parm.B * lp_lat * lp_lat)));
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_eck3& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+
+ // Eckert III
+ template <typename Parameters>
+ void setup_eck3(Parameters& par, par_eck3& proj_parm)
+ {
+ proj_parm.C_x = .42223820031577120149;
+ proj_parm.C_y = .84447640063154240298;
+ proj_parm.A = 1.;
+ proj_parm.B = 0.4052847345693510857755;
+ setup(par, proj_parm);
+ }
+
+ // Putnins P1
+ template <typename Parameters>
+ void setup_putp1(Parameters& par, par_eck3& proj_parm)
+ {
+ proj_parm.C_x = 1.89490;
+ proj_parm.C_y = 0.94745;
+ proj_parm.A = -0.5;
+ proj_parm.B = 0.30396355092701331433;
+ setup(par, proj_parm);
+ }
+
+ // Wagner VI
+ template <typename Parameters>
+ void setup_wag6(Parameters& par, par_eck3& proj_parm)
+ {
+ proj_parm.C_x = proj_parm.C_y = 0.94745;
+ proj_parm.A = 0.;
+ proj_parm.B = 0.30396355092701331433;
+ setup(par, proj_parm);
+ }
+
+ // Kavraisky VII
+ template <typename Parameters>
+ void setup_kav7(Parameters& par, par_eck3& proj_parm)
+ {
+ proj_parm.C_x = 0.2632401569273184856851;
+ proj_parm.C_x = 0.8660254037844;
+ proj_parm.C_y = 1.;
+ proj_parm.A = 0.;
+ proj_parm.B = 0.30396355092701331433;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::eck3
+ #endif // doxygen
+
+ /*!
+ \brief Eckert III projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck3.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct eck3_spheroid : public detail::eck3::base_eck3_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline eck3_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eck3::setup_eck3(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Putnins P1 projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp1.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp1_spheroid : public detail::eck3::base_eck3_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp1_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eck3::setup_putp1(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Wagner VI projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_wag6.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wag6_spheroid : public detail::eck3::base_eck3_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wag6_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eck3::setup_wag6(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Kavraisky VII projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_kav7.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct kav7_spheroid : public detail::eck3::base_eck3_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline kav7_spheroid(const Parameters& par) : detail::eck3::base_eck3_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eck3::setup_kav7(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class eck3_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck3_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp1_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp1_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wag6_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wag6_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class kav7_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<kav7_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void eck3_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("eck3", new eck3_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("putp1", new putp1_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("wag6", new wag6_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("kav7", new kav7_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK3_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/eck4.hpp b/src/boost/geometry/extensions/gis/projections/proj/eck4.hpp
new file mode 100644
index 0000000..38c67f1
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/eck4.hpp
@@ -0,0 +1,167 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck4{
+ static const double C_x = .42223820031577120149;
+ static const double C_y = 1.32650042817700232218;
+ static const double RC_y = .75386330736002178205;
+ static const double C_p = 3.57079632679489661922;
+ static const double RC_p = .28004957675577868795;
+ static const double EPS = 1e-7;
+ static const int NITER = 6;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_eck4_spheroid : public base_t_fi<base_eck4_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_eck4_spheroid(const Parameters& par)
+ : base_t_fi<base_eck4_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double p, V, s, c;
+ int i;
+
+ p = C_p * sin(lp_lat);
+ V = lp_lat * lp_lat;
+ lp_lat *= 0.895168 + V * ( 0.0218849 + V * 0.00826809 );
+ for (i = NITER; i ; --i) {
+ c = cos(lp_lat);
+ s = sin(lp_lat);
+ lp_lat -= V = (lp_lat + s * (c + 2.) - p) /
+ (1. + c * (c + 2.) - s * s);
+ if (fabs(V) < EPS)
+ break;
+ }
+ if (!i) {
+ xy_x = C_x * lp_lon;
+ xy_y = lp_lat < 0. ? -C_y : C_y;
+ } else {
+ xy_x = C_x * lp_lon * (1. + cos(lp_lat));
+ xy_y = C_y * sin(lp_lat);
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double c;
+
+ lp_lat = aasin(xy_y / C_y);
+ lp_lon = xy_x / (C_x * (1. + (c = cos(lp_lat))));
+ lp_lat = aasin((lp_lat + sin(lp_lat) * (c + 2.)) / C_p);
+ }
+ };
+
+ // Eckert IV
+ template <typename Parameters>
+ void setup_eck4(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::eck4
+ #endif // doxygen
+
+ /*!
+ \brief Eckert IV projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck4.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct eck4_spheroid : public detail::eck4::base_eck4_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline eck4_spheroid(const Parameters& par) : detail::eck4::base_eck4_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eck4::setup_eck4(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class eck4_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck4_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void eck4_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("eck4", new eck4_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK4_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/eck5.hpp b/src/boost/geometry/extensions/gis/projections/proj/eck5.hpp
new file mode 100644
index 0000000..15032dd
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/eck5.hpp
@@ -0,0 +1,141 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eck5{
+ static const double XF = 0.44101277172455148219;
+ static const double RXF = 2.26750802723822639137;
+ static const double YF = 0.88202554344910296438;
+ static const double RYF = 1.13375401361911319568;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_eck5_spheroid : public base_t_fi<base_eck5_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_eck5_spheroid(const Parameters& par)
+ : base_t_fi<base_eck5_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = XF * (1. + cos(lp_lat)) * lp_lon;
+ xy_y = YF * lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lon = RXF * xy_x / (1. + cos( lp_lat = RYF * xy_y));
+ }
+ };
+
+ // Eckert V
+ template <typename Parameters>
+ void setup_eck5(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::eck5
+ #endif // doxygen
+
+ /*!
+ \brief Eckert V projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck5.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct eck5_spheroid : public detail::eck5::base_eck5_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline eck5_spheroid(const Parameters& par) : detail::eck5::base_eck5_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eck5::setup_eck5(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class eck5_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck5_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void eck5_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("eck5", new eck5_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ECK5_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/eqc.hpp b/src/boost/geometry/extensions/gis/projections/proj/eqc.hpp
new file mode 100644
index 0000000..f66f803
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/eqc.hpp
@@ -0,0 +1,146 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_EQC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_EQC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eqc{
+
+ struct par_eqc
+ {
+ double rc;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_eqc_spheroid : public base_t_fi<base_eqc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_eqc m_proj_parm;
+
+ inline base_eqc_spheroid(const Parameters& par)
+ : base_t_fi<base_eqc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = this->m_proj_parm.rc * lp_lon;
+ xy_y = lp_lat - this->m_par.phi0;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lon = xy_x / this->m_proj_parm.rc;
+ lp_lat = xy_y + this->m_par.phi0;
+ }
+ };
+
+ // Equidistant Cylindrical (Plate Caree)
+ template <typename Parameters>
+ void setup_eqc(Parameters& par, par_eqc& proj_parm)
+ {
+ if ((proj_parm.rc = cos(pj_param(par.params, "rlat_ts").f)) <= 0.) throw proj_exception(-24);
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::eqc
+ #endif // doxygen
+
+ /*!
+ \brief Equidistant Cylindrical (Plate Caree) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - lat_ts=[
+ - lat_0=0]
+ \par Example
+ \image html ex_eqc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct eqc_spheroid : public detail::eqc::base_eqc_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline eqc_spheroid(const Parameters& par) : detail::eqc::base_eqc_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eqc::setup_eqc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class eqc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eqc_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void eqc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("eqc", new eqc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_EQC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/eqdc.hpp b/src/boost/geometry/extensions/gis/projections/proj/eqdc.hpp
new file mode 100644
index 0000000..7b5f681
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/eqdc.hpp
@@ -0,0 +1,212 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace eqdc{
+ static const double EPS10 = 1.e-10;
+
+ struct par_eqdc
+ {
+ double phi1;
+ double phi2;
+ double n;
+ double rho;
+ double rho0;
+ double c;
+ double en[EN_SIZE];
+ int ellips;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_eqdc_ellipsoid : public base_t_fi<base_eqdc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ mutable par_eqdc m_proj_parm;
+
+ inline base_eqdc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_eqdc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ this->m_proj_parm.rho = this->m_proj_parm.c - (this->m_proj_parm.ellips ? pj_mlfn(lp_lat, sin(lp_lat),
+ cos(lp_lat), this->m_proj_parm.en) : lp_lat);
+ xy_x = this->m_proj_parm.rho * sin( lp_lon *= this->m_proj_parm.n );
+ xy_y = this->m_proj_parm.rho0 - this->m_proj_parm.rho * cos(lp_lon);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ if ((this->m_proj_parm.rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0 ) {
+ if (this->m_proj_parm.n < 0.) {
+ this->m_proj_parm.rho = -this->m_proj_parm.rho;
+ xy_x = -xy_x;
+ xy_y = -xy_y;
+ }
+ lp_lat = this->m_proj_parm.c - this->m_proj_parm.rho;
+ if (this->m_proj_parm.ellips)
+ lp_lat = pj_inv_mlfn(lp_lat, this->m_par.es, this->m_proj_parm.en);
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ } else {
+ lp_lon = 0.;
+ lp_lat = this->m_proj_parm.n > 0. ? HALFPI : - HALFPI;
+ }
+ }
+
+ #ifdef SPECIAL_FACTORS_NOT_CONVERTED
+ inline void fac(Geographic lp, Factors &fac) const
+ {
+ double sinphi, cosphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ this->m_fac.code |= IS_ANAL_HK;
+ this->m_fac.h = 1.;
+ this->m_fac.k = this->m_proj_parm.n * (this->m_proj_parm.c - (this->m_proj_parm.ellips ? pj_mlfn(lp_lat, sinphi,
+ cosphi, this->m_proj_parm.en) : lp_lat)) / pj_msfn(sinphi, cosphi, this->m_par.es);
+ }
+ #endif
+ };
+
+ // Equidistant Conic
+ template <typename Parameters>
+ void setup_eqdc(Parameters& par, par_eqdc& proj_parm)
+ {
+ double cosphi, sinphi;
+ int secant;
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ proj_parm.phi2 = pj_param(par.params, "rlat_2").f;
+ if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10) throw proj_exception(-21);
+ pj_enfn(par.es, proj_parm.en);
+
+ proj_parm.n = sinphi = sin(proj_parm.phi1);
+ cosphi = cos(proj_parm.phi1);
+ secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10;
+ if( (proj_parm.ellips = (par.es > 0.)) ) {
+ double ml1, m1;
+ m1 = pj_msfn(sinphi, cosphi, par.es);
+ ml1 = pj_mlfn(proj_parm.phi1, sinphi, cosphi, proj_parm.en);
+ if (secant) { /* secant cone */
+ sinphi = sin(proj_parm.phi2);
+ cosphi = cos(proj_parm.phi2);
+ proj_parm.n = (m1 - pj_msfn(sinphi, cosphi, par.es)) /
+ (pj_mlfn(proj_parm.phi2, sinphi, cosphi, proj_parm.en) - ml1);
+ }
+ proj_parm.c = ml1 + m1 / proj_parm.n;
+ proj_parm.rho0 = proj_parm.c - pj_mlfn(par.phi0, sin(par.phi0),
+ cos(par.phi0), proj_parm.en);
+ } else {
+ if (secant)
+ proj_parm.n = (cosphi - cos(proj_parm.phi2)) / (proj_parm.phi2 - proj_parm.phi1);
+ proj_parm.c = proj_parm.phi1 + cos(proj_parm.phi1) / proj_parm.n;
+ proj_parm.rho0 = proj_parm.c - par.phi0;
+ }
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ // par.spc = fac;
+ }
+
+ }} // namespace detail::eqdc
+ #endif // doxygen
+
+ /*!
+ \brief Equidistant Conic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ - lat_1= lat_2=
+ \par Example
+ \image html ex_eqdc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct eqdc_ellipsoid : public detail::eqdc::base_eqdc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline eqdc_ellipsoid(const Parameters& par) : detail::eqdc::base_eqdc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::eqdc::setup_eqdc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class eqdc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eqdc_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void eqdc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("eqdc", new eqdc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_EQDC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/fahey.hpp b/src/boost/geometry/extensions/gis/projections/proj/fahey.hpp
new file mode 100644
index 0000000..499a955
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/fahey.hpp
@@ -0,0 +1,140 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace fahey{
+ static const double TOL = 1e-6;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_fahey_spheroid : public base_t_fi<base_fahey_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_fahey_spheroid(const Parameters& par)
+ : base_t_fi<base_fahey_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_y = 1.819152 * ( xy_x = tan(0.5 * lp_lat) );
+ xy_x = 0.819152 * lp_lon * asqrt(1 - xy_x * xy_x);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = 2. * atan(xy_y /= 1.819152);
+ lp_lon = fabs(xy_y = 1. - xy_y * xy_y) < TOL ? 0. :
+ xy_x / (0.819152 * sqrt(xy_y));
+ }
+ };
+
+ // Fahey
+ template <typename Parameters>
+ void setup_fahey(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::fahey
+ #endif // doxygen
+
+ /*!
+ \brief Fahey projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_fahey.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct fahey_spheroid : public detail::fahey::base_fahey_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline fahey_spheroid(const Parameters& par) : detail::fahey::base_fahey_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::fahey::setup_fahey(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class fahey_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<fahey_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void fahey_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("fahey", new fahey_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_FAHEY_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/fouc_s.hpp b/src/boost/geometry/extensions/gis/projections/proj/fouc_s.hpp
new file mode 100644
index 0000000..179a373
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/fouc_s.hpp
@@ -0,0 +1,167 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace fouc_s{
+ static const int MAX_ITER = 10;
+ static const double LOOP_TOL = 1e-7;
+
+ struct par_fouc_s
+ {
+ double n, n1;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_fouc_s_spheroid : public base_t_fi<base_fouc_s_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_fouc_s m_proj_parm;
+
+ inline base_fouc_s_spheroid(const Parameters& par)
+ : base_t_fi<base_fouc_s_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double t;
+
+ t = cos(lp_lat);
+ xy_x = lp_lon * t / (this->m_proj_parm.n + this->m_proj_parm.n1 * t);
+ xy_y = this->m_proj_parm.n * lp_lat + this->m_proj_parm.n1 * sin(lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double V;
+ int i;
+
+ if (this->m_proj_parm.n) {
+ lp_lat = xy_y;
+ for (i = MAX_ITER; i ; --i) {
+ lp_lat -= V = (this->m_proj_parm.n * lp_lat + this->m_proj_parm.n1 * sin(lp_lat) - xy_y ) /
+ (this->m_proj_parm.n + this->m_proj_parm.n1 * cos(lp_lat));
+ if (fabs(V) < LOOP_TOL)
+ break;
+ }
+ if (!i)
+ lp_lat = xy_y < 0. ? -HALFPI : HALFPI;
+ } else
+ lp_lat = aasin(xy_y);
+ V = cos(lp_lat);
+ lp_lon = xy_x * (this->m_proj_parm.n + this->m_proj_parm.n1 * V) / V;
+ }
+ };
+
+ // Foucaut Sinusoidal
+ template <typename Parameters>
+ void setup_fouc_s(Parameters& par, par_fouc_s& proj_parm)
+ {
+ proj_parm.n = pj_param(par.params, "dn").f;
+ if (proj_parm.n < 0. || proj_parm.n > 1.)
+ throw proj_exception(-99);
+ proj_parm.n1 = 1. - proj_parm.n;
+ par.es = 0;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::fouc_s
+ #endif // doxygen
+
+ /*!
+ \brief Foucaut Sinusoidal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_fouc_s.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct fouc_s_spheroid : public detail::fouc_s::base_fouc_s_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline fouc_s_spheroid(const Parameters& par) : detail::fouc_s::base_fouc_s_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::fouc_s::setup_fouc_s(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class fouc_s_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<fouc_s_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void fouc_s_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("fouc_s", new fouc_s_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_FOUC_S_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/gall.hpp b/src/boost/geometry/extensions/gis/projections/proj/gall.hpp
new file mode 100644
index 0000000..f6713ab
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/gall.hpp
@@ -0,0 +1,142 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GALL_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GALL_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gall{
+ static const double YF = 1.70710678118654752440;
+ static const double XF = 0.70710678118654752440;
+ static const double RYF = 0.58578643762690495119;
+ static const double RXF = 1.41421356237309504880;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_gall_spheroid : public base_t_fi<base_gall_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_gall_spheroid(const Parameters& par)
+ : base_t_fi<base_gall_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = XF * lp_lon;
+ xy_y = YF * tan(.5 * lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lon = RXF * xy_x;
+ lp_lat = 2. * atan(xy_y * RYF);
+ }
+ };
+
+ // Gall (Gall Stereographic)
+ template <typename Parameters>
+ void setup_gall(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::gall
+ #endif // doxygen
+
+ /*!
+ \brief Gall (Gall Stereographic) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_gall.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct gall_spheroid : public detail::gall::base_gall_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline gall_spheroid(const Parameters& par) : detail::gall::base_gall_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gall::setup_gall(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class gall_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gall_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void gall_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("gall", new gall_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GALL_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/geocent.hpp b/src/boost/geometry/extensions/gis/projections/proj/geocent.hpp
new file mode 100644
index 0000000..56ff6e7
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/geocent.hpp
@@ -0,0 +1,143 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace geocent{
+
+
+
+
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_geocent_other : public base_t_fi<base_geocent_other<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_geocent_other(const Parameters& par)
+ : base_t_fi<base_geocent_other<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = lp_lon;
+ xy_y = lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y;
+ lp_lon = xy_x;
+ }
+ };
+
+ // Geocentric
+ template <typename Parameters>
+ void setup_geocent(Parameters& par)
+ {
+ par.is_geocent = 1;
+
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ // par.inv = inverse;
+ // par.fwd = forward;
+ }
+
+ }} // namespace detail::geocent
+ #endif // doxygen
+
+ /*!
+ \brief Geocentric projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ \par Example
+ \image html ex_geocent.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct geocent_other : public detail::geocent::base_geocent_other<Geographic, Cartesian, Parameters>
+ {
+ inline geocent_other(const Parameters& par) : detail::geocent::base_geocent_other<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::geocent::setup_geocent(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class geocent_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<geocent_other<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void geocent_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("geocent", new geocent_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GEOCENT_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/geos.hpp b/src/boost/geometry/extensions/gis/projections/proj/geos.hpp
new file mode 100644
index 0000000..712c159
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/geos.hpp
@@ -0,0 +1,280 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace geos{
+
+ struct par_geos
+ {
+ double h;
+ double radius_p;
+ double radius_p2;
+ double radius_p_inv2;
+ double radius_g;
+ double radius_g_1;
+ double C;
+ };
+
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_geos_ellipsoid : public base_t_fi<base_geos_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_geos m_proj_parm;
+
+ inline base_geos_ellipsoid(const Parameters& par)
+ : base_t_fi<base_geos_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double r, Vx, Vy, Vz, tmp;
+
+ /* Calculation of geocentric latitude. */
+ lp_lat = atan (this->m_proj_parm.radius_p2 * tan (lp_lat));
+ /* Calculation of the three components of the vector from satellite to
+ ** position on earth surface (lon,lat).*/
+ r = (this->m_proj_parm.radius_p) / boost::math::hypot(this->m_proj_parm.radius_p * cos (lp_lat), sin (lp_lat));
+ Vx = r * cos (lp_lon) * cos (lp_lat);
+ Vy = r * sin (lp_lon) * cos (lp_lat);
+ Vz = r * sin (lp_lat);
+ /* Check visibility. */
+ if (((this->m_proj_parm.radius_g - Vx) * Vx - Vy * Vy - Vz * Vz * this->m_proj_parm.radius_p_inv2) < 0.)
+ throw proj_exception();;
+ /* Calculation based on view angles from satellite. */
+ tmp = this->m_proj_parm.radius_g - Vx;
+ xy_x = this->m_proj_parm.radius_g_1 * atan (Vy / tmp);
+ xy_y = this->m_proj_parm.radius_g_1 * atan (Vz / boost::math::hypot (Vy, tmp));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double Vx, Vy, Vz, a, b, det, k;
+
+ /* Setting three components of vector from satellite to position.*/
+ Vx = -1.0;
+ Vy = tan (xy_x / this->m_proj_parm.radius_g_1);
+ Vz = tan (xy_y / this->m_proj_parm.radius_g_1) * boost::math::hypot(1.0, Vy);
+ /* Calculation of terms in cubic equation and determinant.*/
+ a = Vz / this->m_proj_parm.radius_p;
+ a = Vy * Vy + a * a + Vx * Vx;
+ b = 2 * this->m_proj_parm.radius_g * Vx;
+ if ((det = (b * b) - 4 * a * this->m_proj_parm.C) < 0.) throw proj_exception();;
+ /* Calculation of three components of vector from satellite to position.*/
+ k = (-b - sqrt(det)) / (2. * a);
+ Vx = this->m_proj_parm.radius_g + k * Vx;
+ Vy *= k;
+ Vz *= k;
+ /* Calculation of longitude and latitude.*/
+ lp_lon = atan2 (Vy, Vx);
+ lp_lat = atan (Vz * cos (lp_lon) / Vx);
+ lp_lat = atan (this->m_proj_parm.radius_p_inv2 * tan (lp_lat));
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_geos_spheroid : public base_t_fi<base_geos_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_geos m_proj_parm;
+
+ inline base_geos_spheroid(const Parameters& par)
+ : base_t_fi<base_geos_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double Vx, Vy, Vz, tmp;
+
+ /* Calculation of the three components of the vector from satellite to
+ ** position on earth surface (lon,lat).*/
+ tmp = cos(lp_lat);
+ Vx = cos (lp_lon) * tmp;
+ Vy = sin (lp_lon) * tmp;
+ Vz = sin (lp_lat);
+ /* Check visibility.*/
+ if (((this->m_proj_parm.radius_g - Vx) * Vx - Vy * Vy - Vz * Vz) < 0.) throw proj_exception();;
+ /* Calculation based on view angles from satellite.*/
+ tmp = this->m_proj_parm.radius_g - Vx;
+ xy_x = this->m_proj_parm.radius_g_1 * atan(Vy / tmp);
+ xy_y = this->m_proj_parm.radius_g_1 * atan(Vz / boost::math::hypot(Vy, tmp));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double Vx, Vy, Vz, a, b, det, k;
+
+ /* Setting three components of vector from satellite to position.*/
+ Vx = -1.0;
+ Vy = tan (xy_x / (this->m_proj_parm.radius_g - 1.0));
+ Vz = tan (xy_y / (this->m_proj_parm.radius_g - 1.0)) * sqrt (1.0 + Vy * Vy);
+ /* Calculation of terms in cubic equation and determinant.*/
+ a = Vy * Vy + Vz * Vz + Vx * Vx;
+ b = 2 * this->m_proj_parm.radius_g * Vx;
+ if ((det = (b * b) - 4 * a * this->m_proj_parm.C) < 0.) throw proj_exception();;
+ /* Calculation of three components of vector from satellite to position.*/
+ k = (-b - sqrt(det)) / (2 * a);
+ Vx = this->m_proj_parm.radius_g + k * Vx;
+ Vy *= k;
+ Vz *= k;
+ /* Calculation of longitude and latitude.*/
+ lp_lon = atan2 (Vy, Vx);
+ lp_lat = atan (Vz * cos (lp_lon) / Vx);
+ }
+ };
+
+ // Geostationary Satellite View
+ template <typename Parameters>
+ void setup_geos(Parameters& par, par_geos& proj_parm)
+ {
+ if ((proj_parm.h = pj_param(par.params, "dh").f) <= 0.) throw proj_exception(-30);
+ if (par.phi0) throw proj_exception(-46);
+ proj_parm.radius_g = 1. + (proj_parm.radius_g_1 = proj_parm.h / par.a);
+ proj_parm.C = proj_parm.radius_g * proj_parm.radius_g - 1.0;
+ if (par.es) {
+ proj_parm.radius_p = sqrt (par.one_es);
+ proj_parm.radius_p2 = par.one_es;
+ proj_parm.radius_p_inv2 = par.rone_es;
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ proj_parm.radius_p = proj_parm.radius_p2 = proj_parm.radius_p_inv2 = 1.0;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+ }} // namespace detail::geos
+ #endif // doxygen
+
+ /*!
+ \brief Geostationary Satellite View projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ - h=
+ \par Example
+ \image html ex_geos.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct geos_ellipsoid : public detail::geos::base_geos_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline geos_ellipsoid(const Parameters& par) : detail::geos::base_geos_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::geos::setup_geos(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Geostationary Satellite View projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ - h=
+ \par Example
+ \image html ex_geos.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct geos_spheroid : public detail::geos::base_geos_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline geos_spheroid(const Parameters& par) : detail::geos::base_geos_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::geos::setup_geos(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class geos_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<geos_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<geos_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void geos_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("geos", new geos_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GEOS_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/gins8.hpp b/src/boost/geometry/extensions/gis/projections/proj/gins8.hpp
new file mode 100644
index 0000000..6ab6a22
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/gins8.hpp
@@ -0,0 +1,140 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gins8{
+ static const double Cl = 0.000952426;
+ static const double Cp = 0.162388;
+ static const double C12 = 0.08333333333333333;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_gins8_spheroid : public base_t_f<base_gins8_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_gins8_spheroid(const Parameters& par)
+ : base_t_f<base_gins8_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double t = lp_lat * lp_lat;
+
+ xy_y = lp_lat * (1. + t * C12);
+ xy_x = lp_lon * (1. - Cp * t);
+ t = lp_lon * lp_lon;
+ xy_x *= (0.87 - Cl * t * t);
+ }
+ };
+
+ // Ginsburg VIII (TsNIIGAiK)
+ template <typename Parameters>
+ void setup_gins8(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = 0;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::gins8
+ #endif // doxygen
+
+ /*!
+ \brief Ginsburg VIII (TsNIIGAiK) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_gins8.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct gins8_spheroid : public detail::gins8::base_gins8_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline gins8_spheroid(const Parameters& par) : detail::gins8::base_gins8_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gins8::setup_gins8(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class gins8_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<gins8_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void gins8_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("gins8", new gins8_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GINS8_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp b/src/boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp
new file mode 100644
index 0000000..fcc037a
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp
@@ -0,0 +1,380 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gn_sinu{
+ static const double EPS10 = 1e-10;
+ static const int MAX_ITER = 8;
+ static const double LOOP_TOL = 1e-7;
+
+ struct par_gn_sinu
+ {
+ double en[EN_SIZE];
+ double m, n, C_x, C_y;
+ };
+ /* Ellipsoidal Sinusoidal only */
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_gn_sinu_ellipsoid : public base_t_fi<base_gn_sinu_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_gn_sinu m_proj_parm;
+
+ inline base_gn_sinu_ellipsoid(const Parameters& par)
+ : base_t_fi<base_gn_sinu_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double s, c;
+
+ xy_y = pj_mlfn(lp_lat, s = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en);
+ xy_x = lp_lon * c / sqrt(1. - this->m_par.es * s * s);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double s; boost::ignore_unused_variable_warning(s);
+
+ if ((s = fabs(lp_lat = pj_inv_mlfn(xy_y, this->m_par.es, this->m_proj_parm.en))) < HALFPI) {
+ s = sin(lp_lat);
+ lp_lon = xy_x * sqrt(1. - this->m_par.es * s * s) / cos(lp_lat);
+ } else if ((s - EPS10) < HALFPI)
+ lp_lon = 0.;
+ else throw proj_exception();;
+ return;
+ }
+ /* General spherical sinusoidals */
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_gn_sinu_spheroid : public base_t_fi<base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_gn_sinu m_proj_parm;
+
+ inline base_gn_sinu_spheroid(const Parameters& par)
+ : base_t_fi<base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (!this->m_proj_parm.m)
+ lp_lat = this->m_proj_parm.n != 1. ? aasin(this->m_proj_parm.n * sin(lp_lat)): lp_lat;
+ else {
+ double k, V;
+ int i;
+
+ k = this->m_proj_parm.n * sin(lp_lat);
+ for (i = MAX_ITER; i ; --i) {
+ lp_lat -= V = (this->m_proj_parm.m * lp_lat + sin(lp_lat) - k) /
+ (this->m_proj_parm.m + cos(lp_lat));
+ if (fabs(V) < LOOP_TOL)
+ break;
+ }
+ if (!i)
+ throw proj_exception();
+ }
+ xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.m + cos(lp_lat));
+ xy_y = this->m_proj_parm.C_y * lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double s; boost::ignore_unused_variable_warning(s);
+
+ xy_y /= this->m_proj_parm.C_y;
+ lp_lat = this->m_proj_parm.m ? aasin((this->m_proj_parm.m * xy_y + sin(xy_y)) / this->m_proj_parm.n) :
+ ( this->m_proj_parm.n != 1. ? aasin(sin(xy_y) / this->m_proj_parm.n) : xy_y );
+ lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.m + cos(xy_y)));
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_gn_sinu& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ par.es = 0;
+ proj_parm.C_x = (proj_parm.C_y = sqrt((proj_parm.m + 1.) / proj_parm.n))/(proj_parm.m + 1.);
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+
+ // General Sinusoidal Series
+ template <typename Parameters>
+ void setup_gn_sinu(Parameters& par, par_gn_sinu& proj_parm)
+ {
+ if (pj_param(par.params, "tn").i && pj_param(par.params, "tm").i) {
+ proj_parm.n = pj_param(par.params, "dn").f;
+ proj_parm.m = pj_param(par.params, "dm").f;
+ } else
+ throw proj_exception(-99);
+ setup(par, proj_parm);
+ }
+
+ // Sinusoidal (Sanson-Flamsteed)
+ template <typename Parameters>
+ void setup_sinu(Parameters& par, par_gn_sinu& proj_parm)
+ {
+ pj_enfn(par.es, proj_parm.en);
+
+ if (par.es) {
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ proj_parm.n = 1.;
+ proj_parm.m = 0.;
+ setup(par, proj_parm);
+ }
+ }
+
+ // Eckert VI
+ template <typename Parameters>
+ void setup_eck6(Parameters& par, par_gn_sinu& proj_parm)
+ {
+ proj_parm.m = 1.;
+ proj_parm.n = 2.570796326794896619231321691;
+ setup(par, proj_parm);
+ }
+
+ // McBryde-Thomas Flat-Polar Sinusoidal
+ template <typename Parameters>
+ void setup_mbtfps(Parameters& par, par_gn_sinu& proj_parm)
+ {
+ proj_parm.m = 0.5;
+ proj_parm.n = 1.785398163397448309615660845;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::gn_sinu
+ #endif // doxygen
+
+ /*!
+ \brief Sinusoidal (Sanson-Flamsteed) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_sinu.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct sinu_ellipsoid : public detail::gn_sinu::base_gn_sinu_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline sinu_ellipsoid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gn_sinu::setup_sinu(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief General Sinusoidal Series projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - m= n=
+ \par Example
+ \image html ex_gn_sinu.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct gn_sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline gn_sinu_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gn_sinu::setup_gn_sinu(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Sinusoidal (Sanson-Flamsteed) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_sinu.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline sinu_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gn_sinu::setup_sinu(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Eckert VI projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_eck6.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct eck6_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline eck6_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gn_sinu::setup_eck6(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief McBryde-Thomas Flat-Polar Sinusoidal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_mbtfps.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct mbtfps_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline mbtfps_spheroid(const Parameters& par) : detail::gn_sinu::base_gn_sinu_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gn_sinu::setup_mbtfps(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class gn_sinu_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gn_sinu_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class sinu_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<sinu_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<sinu_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class eck6_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<eck6_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class mbtfps_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<mbtfps_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void gn_sinu_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("gn_sinu", new gn_sinu_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("sinu", new sinu_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("eck6", new eck6_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("mbtfps", new mbtfps_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GN_SINU_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/gnom.hpp b/src/boost/geometry/extensions/gis/projections/proj/gnom.hpp
new file mode 100644
index 0000000..3b8e599
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/gnom.hpp
@@ -0,0 +1,227 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gnom{
+ static const double EPS10 = 1.e-10;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ struct par_gnom
+ {
+ double sinph0;
+ double cosph0;
+ int mode;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_gnom_spheroid : public base_t_fi<base_gnom_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_gnom m_proj_parm;
+
+ inline base_gnom_spheroid(const Parameters& par)
+ : base_t_fi<base_gnom_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, cosphi, sinphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ xy_y = cosphi * coslam;
+ break;
+ case OBLIQ:
+ xy_y = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosphi * coslam;
+ break;
+ case S_POLE:
+ xy_y = - sinphi;
+ break;
+ case N_POLE:
+ xy_y = sinphi;
+ break;
+ }
+ if (xy_y <= EPS10) throw proj_exception();;
+ xy_x = (xy_y = 1. / xy_y) * cosphi * sin(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ xy_y *= sinphi;
+ break;
+ case OBLIQ:
+ xy_y *= this->m_proj_parm.cosph0 * sinphi - this->m_proj_parm.sinph0 * cosphi * coslam;
+ break;
+ case N_POLE:
+ coslam = - coslam;
+ case S_POLE:
+ xy_y *= cosphi * coslam;
+ break;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rh, cosz, sinz;
+
+ rh = boost::math::hypot(xy_x, xy_y);
+ sinz = sin(lp_lat = atan(rh));
+ cosz = sqrt(1. - sinz * sinz);
+ if (fabs(rh) <= EPS10) {
+ lp_lat = this->m_par.phi0;
+ lp_lon = 0.;
+ } else {
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ lp_lat = cosz * this->m_proj_parm.sinph0 + xy_y * sinz * this->m_proj_parm.cosph0 / rh;
+ if (fabs(lp_lat) >= 1.)
+ lp_lat = lp_lat > 0. ? HALFPI : - HALFPI;
+ else
+ lp_lat = asin(lp_lat);
+ xy_y = (cosz - this->m_proj_parm.sinph0 * sin(lp_lat)) * rh;
+ xy_x *= sinz * this->m_proj_parm.cosph0;
+ break;
+ case EQUIT:
+ lp_lat = xy_y * sinz / rh;
+ if (fabs(lp_lat) >= 1.)
+ lp_lat = lp_lat > 0. ? HALFPI : - HALFPI;
+ else
+ lp_lat = asin(lp_lat);
+ xy_y = cosz * rh;
+ xy_x *= sinz;
+ break;
+ case S_POLE:
+ lp_lat -= HALFPI;
+ break;
+ case N_POLE:
+ lp_lat = HALFPI - lp_lat;
+ xy_y = -xy_y;
+ break;
+ }
+ lp_lon = atan2(xy_x, xy_y);
+ }
+ }
+ };
+
+ // Gnomonic
+ template <typename Parameters>
+ void setup_gnom(Parameters& par, par_gnom& proj_parm)
+ {
+ if (fabs(fabs(par.phi0) - HALFPI) < EPS10)
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ else if (fabs(par.phi0) < EPS10)
+ proj_parm.mode = EQUIT;
+ else {
+ proj_parm.mode = OBLIQ;
+ proj_parm.sinph0 = sin(par.phi0);
+ proj_parm.cosph0 = cos(par.phi0);
+ }
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::gnom
+ #endif // doxygen
+
+ /*!
+ \brief Gnomonic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ \par Example
+ \image html ex_gnom.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct gnom_spheroid : public detail::gnom::base_gnom_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline gnom_spheroid(const Parameters& par) : detail::gnom::base_gnom_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gnom::setup_gnom(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class gnom_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gnom_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void gnom_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("gnom", new gnom_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GNOM_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/goode.hpp b/src/boost/geometry/extensions/gis/projections/proj/goode.hpp
new file mode 100644
index 0000000..41d4727
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/goode.hpp
@@ -0,0 +1,160 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+#include <boost/geometry/extensions/gis/projections/proj/moll.hpp>
+#include <boost/geometry/extensions/gis/projections/proj/gn_sinu.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace goode{
+ static const double Y_COR = 0.05280;
+ static const double PHI_LIM = .71093078197902358062;
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct par_goode
+ {
+ sinu_ellipsoid<Geographic, Cartesian, Parameters> sinu;
+ moll_spheroid<Geographic, Cartesian, Parameters> moll;
+
+ par_goode(const Parameters& par) : sinu(par), moll(par) {}
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_goode_spheroid : public base_t_fi<base_goode_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_goode<Geographic, Cartesian, Parameters> m_proj_parm;
+
+ inline base_goode_spheroid(const Parameters& par)
+ : base_t_fi<base_goode_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par), m_proj_parm(par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (fabs(lp_lat) <= PHI_LIM)
+ this->m_proj_parm.sinu.fwd(lp_lon, lp_lat, xy_x, xy_y);
+ else {
+ this->m_proj_parm.moll.fwd(lp_lon, lp_lat, xy_x, xy_y);
+ xy_y -= lp_lat >= 0.0 ? Y_COR : -Y_COR;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ if (fabs(xy_y) <= PHI_LIM)
+ this->m_proj_parm.sinu.inv(xy_x, xy_y, lp_lon, lp_lat);
+ else {
+ xy_y += xy_y >= 0.0 ? Y_COR : -Y_COR;
+ this->m_proj_parm.moll.inv(xy_x, xy_y, lp_lon, lp_lat);
+ }
+ }
+ };
+
+ // Goode Homolosine
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ void setup_goode(Parameters& par, par_goode<Geographic, Cartesian, Parameters>& proj_parm)
+ {
+ par.es = 0.;
+ // par.fwd = s_forward;
+ // par.inv = s_inverse;
+ }
+
+ }} // namespace detail::goode
+ #endif // doxygen
+
+ /*!
+ \brief Goode Homolosine projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_goode.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct goode_spheroid : public detail::goode::base_goode_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline goode_spheroid(const Parameters& par) : detail::goode::base_goode_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::goode::setup_goode(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class goode_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<goode_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void goode_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("goode", new goode_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GOODE_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/gstmerc.hpp b/src/boost/geometry/extensions/gis/projections/proj/gstmerc.hpp
new file mode 100644
index 0000000..ac48e0b
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/gstmerc.hpp
@@ -0,0 +1,176 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace gstmerc{
+
+ struct par_gstmerc
+ {
+ double lamc;
+ double phic;
+ double c;
+ double n1;
+ double n2;
+ double XS;
+ double YS;
+ };
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_gstmerc_spheroid : public base_t_fi<base_gstmerc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_gstmerc m_proj_parm;
+
+ inline base_gstmerc_spheroid(const Parameters& par)
+ : base_t_fi<base_gstmerc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double L, Ls, sinLs1, Ls1;
+ L= this->m_proj_parm.n1*lp_lon;
+ Ls= this->m_proj_parm.c+this->m_proj_parm.n1*log(pj_tsfn(-1.0*lp_lat,-1.0*sin(lp_lat),this->m_par.e));
+ sinLs1= sin(L)/cosh(Ls);
+ Ls1= log(pj_tsfn(-1.0*asin(sinLs1),0.0,0.0));
+ xy_x= (this->m_proj_parm.XS + this->m_proj_parm.n2*Ls1)*this->m_par.ra;
+ xy_y= (this->m_proj_parm.YS + this->m_proj_parm.n2*atan(sinh(Ls)/cos(L)))*this->m_par.ra;
+ /*fprintf(stderr,"fwd:\nL =%16.13f\nLs =%16.13f\nLs1 =%16.13f\nLP(%16.13f,%16.13f)=XY(%16.4f,%16.4f)\n",L,Ls,Ls1,lp_lon+this->m_par.lam0,lp_lat,(xy_x*this->m_par.a + this->m_par.x0)*this->m_par.to_meter,(xy_y*this->m_par.a + this->m_par.y0)*this->m_par.to_meter);*/
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double L, LC, sinC;
+ L= atan(sinh((xy_x*this->m_par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2)/cos((xy_y*this->m_par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2));
+ sinC= sin((xy_y*this->m_par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2)/cosh((xy_x*this->m_par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2);
+ LC= log(pj_tsfn(-1.0*asin(sinC),0.0,0.0));
+ lp_lon= L/this->m_proj_parm.n1;
+ lp_lat= -1.0*pj_phi2(exp((LC-this->m_proj_parm.c)/this->m_proj_parm.n1),this->m_par.e);
+ /*fprintf(stderr,"inv:\nL =%16.13f\nsinC =%16.13f\nLC =%16.13f\nXY(%16.4f,%16.4f)=LP(%16.13f,%16.13f)\n",L,sinC,LC,((xy_x/this->m_par.ra)+this->m_par.x0)/this->m_par.to_meter,((xy_y/this->m_par.ra)+this->m_par.y0)/this->m_par.to_meter,lp_lon+this->m_par.lam0,lp_lat);*/
+ }
+ };
+
+ // Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion)
+ template <typename Parameters>
+ void setup_gstmerc(Parameters& par, par_gstmerc& proj_parm)
+ {
+ proj_parm.lamc= par.lam0;
+ proj_parm.n1= sqrt(1.0+par.es*pow(cos(par.phi0),4.0)/(1.0-par.es));
+ proj_parm.phic= asin(sin(par.phi0)/proj_parm.n1);
+ proj_parm.c= log(pj_tsfn(-1.0*proj_parm.phic,0.0,0.0))
+ -proj_parm.n1*log(pj_tsfn(-1.0*par.phi0,-1.0*sin(par.phi0),par.e));
+ proj_parm.n2= par.k0*par.a*sqrt(1.0-par.es)/(1.0-par.es*sin(par.phi0)*sin(par.phi0));
+ proj_parm.XS= 0;
+ /* -par.x0 */
+ proj_parm.YS= -1.0*proj_parm.n2*proj_parm.phic;
+ /* -par.y0 */
+ // par.inv= s_inverse;
+ // par.fwd= s_forward;
+ /*fprintf(stderr,"a (m) =%16.4f\ne =%16.13f\nl0(rad)=%16.13f\np0(rad)=%16.13f\nk0 =%16.4f\nX0 (m)=%16.4f\nY0 (m)=%16.4f\n\nlC(rad)=%16.13f\npC(rad)=%16.13f\nc =%16.13f\nn1 =%16.13f\nn2 (m) =%16.4f\nXS (m) =%16.4f\nYS (m) =%16.4f\n", par.a, par.e, par.lam0, par.phi0, par.k0, par.x0, par.y0, proj_parm.lamc, proj_parm.phic, proj_parm.c, proj_parm.n1, proj_parm.n2, proj_parm.XS +par.x0, proj_parm.YS + par.y0);
+ */
+ }
+
+ }} // namespace detail::gstmerc
+ #endif // doxygen
+
+ /*!
+ \brief Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ - lat_0= lon_0= k_0=
+ \par Example
+ \image html ex_gstmerc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct gstmerc_spheroid : public detail::gstmerc::base_gstmerc_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline gstmerc_spheroid(const Parameters& par) : detail::gstmerc::base_gstmerc_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::gstmerc::setup_gstmerc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class gstmerc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gstmerc_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void gstmerc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("gstmerc", new gstmerc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_GSTMERC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/hammer.hpp b/src/boost/geometry/extensions/gis/projections/proj/hammer.hpp
new file mode 100644
index 0000000..70bcc5d
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/hammer.hpp
@@ -0,0 +1,152 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace hammer{
+
+ struct par_hammer
+ {
+ double w;
+ double m, rm;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_hammer_spheroid : public base_t_f<base_hammer_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_hammer m_proj_parm;
+
+ inline base_hammer_spheroid(const Parameters& par)
+ : base_t_f<base_hammer_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double cosphi, d;
+
+ d = sqrt(2./(1. + (cosphi = cos(lp_lat)) * cos(lp_lon *= this->m_proj_parm.w)));
+ xy_x = this->m_proj_parm.m * d * cosphi * sin(lp_lon);
+ xy_y = this->m_proj_parm.rm * d * sin(lp_lat);
+ }
+ };
+
+ // Hammer & Eckert-Greifendorff
+ template <typename Parameters>
+ void setup_hammer(Parameters& par, par_hammer& proj_parm)
+ {
+ if (pj_param(par.params, "tW").i) {
+ if ((proj_parm.w = fabs(pj_param(par.params, "dW").f)) <= 0.) throw proj_exception(-27);
+ } else
+ proj_parm.w = .5;
+ if (pj_param(par.params, "tM").i) {
+ if ((proj_parm.m = fabs(pj_param(par.params, "dM").f)) <= 0.) throw proj_exception(-27);
+ } else
+ proj_parm.m = 1.;
+ proj_parm.rm = 1. / proj_parm.m;
+ proj_parm.m /= proj_parm.w;
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::hammer
+ #endif // doxygen
+
+ /*!
+ \brief Hammer & Eckert-Greifendorff projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ - W= M=
+ \par Example
+ \image html ex_hammer.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct hammer_spheroid : public detail::hammer::base_hammer_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline hammer_spheroid(const Parameters& par) : detail::hammer::base_hammer_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::hammer::setup_hammer(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class hammer_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<hammer_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void hammer_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("hammer", new hammer_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_HAMMER_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/hatano.hpp b/src/boost/geometry/extensions/gis/projections/proj/hatano.hpp
new file mode 100644
index 0000000..4e16660
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/hatano.hpp
@@ -0,0 +1,173 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace hatano{
+ static const int NITER = 20;
+ static const double EPS = 1e-7;
+ static const double ONETOL = 1.000001;
+ static const double CN = 2.67595;
+ static const double CS = 2.43763;
+ static const double RCN = 0.37369906014686373063;
+ static const double RCS = 0.41023453108141924738;
+ static const double FYCN = 1.75859;
+ static const double FYCS = 1.93052;
+ static const double RYCN = 0.56863737426006061674;
+ static const double RYCS = 0.51799515156538134803;
+ static const double FXC = 0.85;
+ static const double RXC = 1.17647058823529411764;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_hatano_spheroid : public base_t_fi<base_hatano_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_hatano_spheroid(const Parameters& par)
+ : base_t_fi<base_hatano_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double th1, c;
+ int i;
+
+ c = sin(lp_lat) * (lp_lat < 0. ? CS : CN);
+ for (i = NITER; i; --i) {
+ lp_lat -= th1 = (lp_lat + sin(lp_lat) - c) / (1. + cos(lp_lat));
+ if (fabs(th1) < EPS) break;
+ }
+ xy_x = FXC * lp_lon * cos(lp_lat *= .5);
+ xy_y = sin(lp_lat) * (lp_lat < 0. ? FYCS : FYCN);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double th;
+
+ th = xy_y * ( xy_y < 0. ? RYCS : RYCN);
+ if (fabs(th) > 1.)
+ if (fabs(th) > ONETOL) throw proj_exception();
+ else th = th > 0. ? HALFPI : - HALFPI;
+ else
+ th = asin(th);
+ lp_lon = RXC * xy_x / cos(th);
+ th += th;
+ lp_lat = (th + sin(th)) * (xy_y < 0. ? RCS : RCN);
+ if (fabs(lp_lat) > 1.)
+ if (fabs(lp_lat) > ONETOL) throw proj_exception();
+ else lp_lat = lp_lat > 0. ? HALFPI : - HALFPI;
+ else
+ lp_lat = asin(lp_lat);
+ }
+ };
+
+ // Hatano Asymmetrical Equal Area
+ template <typename Parameters>
+ void setup_hatano(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::hatano
+ #endif // doxygen
+
+ /*!
+ \brief Hatano Asymmetrical Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_hatano.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct hatano_spheroid : public detail::hatano::base_hatano_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline hatano_spheroid(const Parameters& par) : detail::hatano::base_hatano_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::hatano::setup_hatano(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class hatano_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<hatano_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void hatano_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("hatano", new hatano_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_HATANO_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/imw_p.hpp b/src/boost/geometry/extensions/gis/projections/proj/imw_p.hpp
new file mode 100644
index 0000000..3270fbe
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/imw_p.hpp
@@ -0,0 +1,281 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace imw_p{
+ static const double TOL = 1e-10;
+ static const double EPS = 1e-10;
+
+ struct PXY { double x, y; }; // x/y projection specific
+
+ struct par_imw_p
+ {
+ double P, Pp, Q, Qp, R_1, R_2, sphi_1, sphi_2, C2;
+ double phi_1, phi_2, lam_1;
+ double en[EN_SIZE];
+ int mode; /* = 0, phi_1 and phi_2 != 0, = 1, phi_1 = 0, = -1 phi_2 = 0 */
+ };
+ template <typename Parameters>
+ inline int
+ phi12(Parameters& par, par_imw_p& proj_parm, double *del, double *sig) {
+ int err = 0;
+
+ if (!pj_param(par.params, "tlat_1").i ||
+ !pj_param(par.params, "tlat_2").i) {
+ err = -41;
+ } else {
+ proj_parm.phi_1 = pj_param(par.params, "rlat_1").f;
+ proj_parm.phi_2 = pj_param(par.params, "rlat_2").f;
+ *del = 0.5 * (proj_parm.phi_2 - proj_parm.phi_1);
+ *sig = 0.5 * (proj_parm.phi_2 + proj_parm.phi_1);
+ err = (fabs(*del) < EPS || fabs(*sig) < EPS) ? -42 : 0;
+ }
+ return err;
+ }
+ template <typename Parameters>
+ inline PXY
+ loc_for(double const& lp_lam, double const& lp_phi, const Parameters& par, par_imw_p const& proj_parm, double *yc) {
+ PXY xy;
+
+ if (! lp_phi) {
+ xy.x = lp_lam;
+ xy.y = 0.;
+ } else {
+ double xa, ya, xb, yb, xc, D, B, m, sp, t, R, C;
+
+ sp = sin(lp_phi);
+ m = pj_mlfn(lp_phi, sp, cos(lp_phi), proj_parm.en);
+ xa = proj_parm.Pp + proj_parm.Qp * m;
+ ya = proj_parm.P + proj_parm.Q * m;
+ R = 1. / (tan(lp_phi) * sqrt(1. - par.es * sp * sp));
+ C = sqrt(R * R - xa * xa);
+ if (lp_phi < 0.) C = - C;
+ C += ya - R;
+ if (proj_parm.mode < 0) {
+ xb = lp_lam;
+ yb = proj_parm.C2;
+ } else {
+ t = lp_lam * proj_parm.sphi_2;
+ xb = proj_parm.R_2 * sin(t);
+ yb = proj_parm.C2 + proj_parm.R_2 * (1. - cos(t));
+ }
+ if (proj_parm.mode > 0) {
+ xc = lp_lam;
+ *yc = 0.;
+ } else {
+ t = lp_lam * proj_parm.sphi_1;
+ xc = proj_parm.R_1 * sin(t);
+ *yc = proj_parm.R_1 * (1. - cos(t));
+ }
+ D = (xb - xc)/(yb - *yc);
+ B = xc + D * (C + R - *yc);
+ xy.x = D * sqrt(R * R * (1 + D * D) - B * B);
+ if (lp_phi > 0)
+ xy.x = - xy.x;
+ xy.x = (B + xy.x) / (1. + D * D);
+ xy.y = sqrt(R * R - xy.x * xy.x);
+ if (lp_phi > 0)
+ xy.y = - xy.y;
+ xy.y += C + R;
+ }
+ return (xy);
+ }
+
+ template <typename Parameters>
+ inline void
+ xy(Parameters& par, par_imw_p& proj_parm, double phi, double *x, double *y, double *sp, double *R) {
+ double F;
+
+ *sp = sin(phi);
+ *R = 1./(tan(phi) * sqrt(1. - par.es * *sp * *sp ));
+ F = proj_parm.lam_1 * *sp;
+ *y = *R * (1 - cos(F));
+ *x = *R * sin(F);
+ }
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_imw_p_ellipsoid : public base_t_fi<base_imw_p_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_imw_p m_proj_parm;
+
+ inline base_imw_p_ellipsoid(const Parameters& par)
+ : base_t_fi<base_imw_p_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double yc = 0;
+ PXY xy = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc);
+ xy_x = xy.x; xy_y = xy.y;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ PXY t;
+ double yc = 0;
+
+ lp_lat = this->m_proj_parm.phi_2;
+ lp_lon = xy_x / cos(lp_lat);
+ do {
+ t = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc);
+ lp_lat = ((lp_lat - this->m_proj_parm.phi_1) * (xy_y - yc) / (t.y - yc)) + this->m_proj_parm.phi_1;
+ lp_lon = lp_lon * xy_x / t.x;
+ } while (fabs(t.x - xy_x) > TOL || fabs(t.y - xy_y) > TOL);
+ }
+ };
+
+ // International Map of the World Polyconic
+ template <typename Parameters>
+ void setup_imw_p(Parameters& par, par_imw_p& proj_parm)
+ {
+ double del, sig, s, t, x1, x2, T2, y1, m1, m2, y2;
+ int i;
+ pj_enfn(par.es, proj_parm.en);
+ if( (i = phi12(par, proj_parm, &del, &sig)) != 0)
+ throw proj_exception(i);
+ if (proj_parm.phi_2 < proj_parm.phi_1) { /* make sure proj_parm.phi_1 most southerly */
+ del = proj_parm.phi_1;
+ proj_parm.phi_1 = proj_parm.phi_2;
+ proj_parm.phi_2 = del;
+ }
+ if (pj_param(par.params, "tlon_1").i)
+ proj_parm.lam_1 = pj_param(par.params, "rlon_1").f;
+ else { /* use predefined based upon latitude */
+ sig = fabs(sig * RAD_TO_DEG);
+ if (sig <= 60) sig = 2.;
+ else if (sig <= 76) sig = 4.;
+ else sig = 8.;
+ proj_parm.lam_1 = sig * DEG_TO_RAD;
+ }
+ proj_parm.mode = 0;
+ if (proj_parm.phi_1) xy(par, proj_parm, proj_parm.phi_1, &x1, &y1, &proj_parm.sphi_1, &proj_parm.R_1);
+ else {
+ proj_parm.mode = 1;
+ y1 = 0.;
+ x1 = proj_parm.lam_1;
+ }
+ if (proj_parm.phi_2) xy(par, proj_parm, proj_parm.phi_2, &x2, &T2, &proj_parm.sphi_2, &proj_parm.R_2);
+ else {
+ proj_parm.mode = -1;
+ T2 = 0.;
+ x2 = proj_parm.lam_1;
+ }
+ m1 = pj_mlfn(proj_parm.phi_1, proj_parm.sphi_1, cos(proj_parm.phi_1), proj_parm.en);
+ m2 = pj_mlfn(proj_parm.phi_2, proj_parm.sphi_2, cos(proj_parm.phi_2), proj_parm.en);
+ t = m2 - m1;
+ s = x2 - x1;
+ y2 = sqrt(t * t - s * s) + y1;
+ proj_parm.C2 = y2 - T2;
+ t = 1. / t;
+ proj_parm.P = (m2 * y1 - m1 * y2) * t;
+ proj_parm.Q = (y2 - y1) * t;
+ proj_parm.Pp = (m2 * x1 - m1 * x2) * t;
+ proj_parm.Qp = (x2 - x1) * t;
+ // par.fwd = e_forward;
+ // par.inv = e_inverse;
+ }
+
+ }} // namespace detail::imw_p
+ #endif // doxygen
+
+ /*!
+ \brief International Map of the World Polyconic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Mod Polyconic
+ - Ellipsoid
+ - lat_1= and lat_2= [lon_1=]
+ \par Example
+ \image html ex_imw_p.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct imw_p_ellipsoid : public detail::imw_p::base_imw_p_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline imw_p_ellipsoid(const Parameters& par) : detail::imw_p::base_imw_p_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::imw_p::setup_imw_p(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class imw_p_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<imw_p_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void imw_p_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("imw_p", new imw_p_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_IMW_P_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/krovak.hpp b/src/boost/geometry/extensions/gis/projections/proj/krovak.hpp
new file mode 100644
index 0000000..39b4a94
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/krovak.hpp
@@ -0,0 +1,338 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace krovak{
+
+ struct par_krovak
+ {
+ double C_x;
+ };
+
+
+
+
+
+ /**
+ NOTES: According to EPSG the full Krovak projection method should have
+ the following parameters. Within PROJ.4 the azimuth, and pseudo
+ standard parallel are hardcoded in the algorithm and can't be
+ altered from outside. The others all have defaults to match the
+ common usage with Krovak projection.
+
+ lat_0 = latitude of centre of the projection
+
+ lon_0 = longitude of centre of the projection
+
+ ** = azimuth (true) of the centre line passing through the centre of the projection
+
+ ** = latitude of pseudo standard parallel
+
+ k = scale factor on the pseudo standard parallel
+
+ x_0 = False Easting of the centre of the projection at the apex of the cone
+
+ y_0 = False Northing of the centre of the projection at the apex of the cone
+
+ **/
+
+
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_krovak_ellipsoid : public base_t_fi<base_krovak_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_krovak m_proj_parm;
+
+ inline base_krovak_ellipsoid(const Parameters& par)
+ : base_t_fi<base_krovak_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ /* calculate xy from lat/lon */
+
+
+
+
+ /* Constants, identical to inverse transform function */
+ double s45, s90, e2, e, alfa, uq, u0, g, k, k1, n0, ro0, ad, a, s0, n;
+ double gfi, u, fi0, deltav, s, d, eps, ro;
+
+
+ s45 = 0.785398163397448; /* 45 DEG */
+ s90 = 2 * s45;
+ fi0 = this->m_par.phi0; /* Latitude of projection centre 49 DEG 30' */
+
+ /* Ellipsoid is used as Parameter in for.c and inv.c, therefore a must
+ be set to 1 here.
+ Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128,
+ e2=0.006674372230614;
+ */
+ a = 1; /* 6377397.155; */
+ /* e2 = this->m_par.es;*/ /* 0.006674372230614; */
+ e2 = 0.006674372230614;
+ e = sqrt(e2);
+
+ alfa = sqrt(1. + (e2 * pow(cos(fi0), 4)) / (1. - e2));
+
+ uq = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */
+ u0 = asin(sin(fi0) / alfa);
+ g = pow( (1. + e * sin(fi0)) / (1. - e * sin(fi0)) , alfa * e / 2. );
+
+ k = tan( u0 / 2. + s45) / pow (tan(fi0 / 2. + s45) , alfa) * g;
+
+ k1 = this->m_par.k0;
+ n0 = a * sqrt(1. - e2) / (1. - e2 * pow(sin(fi0), 2));
+ s0 = 1.37008346281555; /* Latitude of pseudo standard parallel 78 DEG 30'00" N */
+ n = sin(s0);
+ ro0 = k1 * n0 / tan(s0);
+ ad = s90 - uq;
+
+ /* Transformation */
+
+ gfi =pow ( ((1. + e * sin(lp_lat)) /
+ (1. - e * sin(lp_lat))) , (alfa * e / 2.));
+
+ u= 2. * (atan(k * pow( tan(lp_lat / 2. + s45), alfa) / gfi)-s45);
+
+ deltav = - lp_lon * alfa;
+
+ s = asin(cos(ad) * sin(u) + sin(ad) * cos(u) * cos(deltav));
+ d = asin(cos(u) * sin(deltav) / cos(s));
+ eps = n * d;
+ ro = ro0 * pow(tan(s0 / 2. + s45) , n) / pow(tan(s / 2. + s45) , n) ;
+
+ /* x and y are reverted! */
+ xy_y = ro * cos(eps) / a;
+ xy_x = ro * sin(eps) / a;
+
+ if( !pj_param(this->m_par.params, "tczech").i )
+ {
+ xy_y *= -1.0;
+ xy_x *= -1.0;
+ }
+
+ return;
+ }
+
+
+
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ /* calculate lat/lon from xy */
+
+ /* Constants, identisch wie in der Umkehrfunktion */
+ double s45, s90, fi0, e2, e, alfa, uq, u0, g, k, k1, n0, ro0, ad, a, s0, n;
+ double u, deltav, s, d, eps, ro, fi1, xy0;
+ int ok;
+
+ s45 = 0.785398163397448; /* 45 DEG */
+ s90 = 2 * s45;
+ fi0 = this->m_par.phi0; /* Latitude of projection centre 49 DEG 30' */
+
+
+ /* Ellipsoid is used as Parameter in for.c and inv.c, therefore a must
+ be set to 1 here.
+ Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128,
+ e2=0.006674372230614;
+ */
+ a = 1; /* 6377397.155; */
+ /* e2 = this->m_par.es; */ /* 0.006674372230614; */
+ e2 = 0.006674372230614;
+ e = sqrt(e2);
+
+ alfa = sqrt(1. + (e2 * pow(cos(fi0), 4)) / (1. - e2));
+ uq = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */
+ u0 = asin(sin(fi0) / alfa);
+ g = pow( (1. + e * sin(fi0)) / (1. - e * sin(fi0)) , alfa * e / 2. );
+
+ k = tan( u0 / 2. + s45) / pow (tan(fi0 / 2. + s45) , alfa) * g;
+
+ k1 = this->m_par.k0;
+ n0 = a * sqrt(1. - e2) / (1. - e2 * pow(sin(fi0), 2));
+ s0 = 1.37008346281555; /* Latitude of pseudo standard parallel 78 DEG 30'00" N */
+ n = sin(s0);
+ ro0 = k1 * n0 / tan(s0);
+ ad = s90 - uq;
+
+
+ /* Transformation */
+ /* revert y, x*/
+ xy0=xy_x;
+ xy_x=xy_y;
+ xy_y=xy0;
+
+ if( !pj_param(this->m_par.params, "tczech").i )
+ {
+ xy_x *= -1.0;
+ xy_y *= -1.0;
+ }
+
+ ro = sqrt(xy_x * xy_x + xy_y * xy_y);
+ eps = atan2(xy_y, xy_x);
+ d = eps / sin(s0);
+ s = 2. * (atan( pow(ro0 / ro, 1. / n) * tan(s0 / 2. + s45)) - s45);
+
+ u = asin(cos(ad) * sin(s) - sin(ad) * cos(s) * cos(d));
+ deltav = asin(cos(s) * sin(d) / cos(u));
+
+ lp_lon = this->m_par.lam0 - deltav / alfa;
+
+ /* ITERATION FOR lp_lat */
+ fi1 = u;
+
+ ok = 0;
+ do
+ {
+ lp_lat = 2. * ( atan( pow( k, -1. / alfa) *
+ pow( tan(u / 2. + s45) , 1. / alfa) *
+ pow( (1. + e * sin(fi1)) / (1. - e * sin(fi1)) , e / 2.)
+ ) - s45);
+
+ if (fabs(fi1 - lp_lat) < 0.000000000000001) ok=1;
+ fi1 = lp_lat;
+
+ }
+ while (ok==0);
+
+ lp_lon -= this->m_par.lam0;
+
+ return;
+ }
+
+ };
+
+ // Krovak
+ template <typename Parameters>
+ void setup_krovak(Parameters& par, par_krovak& proj_parm)
+ {
+ double ts;
+ /* read some Parameters,
+ * here Latitude Truescale */
+ ts = pj_param(par.params, "rlat_ts").f;
+ proj_parm.C_x = ts;
+
+ /* we want Bessel as fixed ellipsoid */
+ par.a = 6377397.155;
+ par.e = sqrt(par.es = 0.006674372230614);
+ /* if latitude of projection center is not set, use 49d30'N */
+ if (!pj_param(par.params, "tlat_0").i)
+ par.phi0 = 0.863937979737193;
+
+ /* if center long is not set use 42d30'E of Ferro - 17d40' for Ferro */
+ /* that will correspond to using longitudes relative to greenwich */
+ /* as input and output, instead of lat/long relative to Ferro */
+ if (!pj_param(par.params, "tlon_0").i)
+ par.lam0 = 0.7417649320975901 - 0.308341501185665;
+ /* if scale not set default to 0.9999 */
+ if (!pj_param(par.params, "tk").i)
+ par.k0 = 0.9999;
+ /* always the same */
+ // par.inv = e_inverse;
+
+ // par.fwd = e_forward;
+ }
+
+ }} // namespace detail::krovak
+ #endif // doxygen
+
+ /*!
+ \brief Krovak projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Ellps
+ \par Example
+ \image html ex_krovak.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct krovak_ellipsoid : public detail::krovak::base_krovak_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline krovak_ellipsoid(const Parameters& par) : detail::krovak::base_krovak_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::krovak::setup_krovak(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class krovak_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<krovak_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void krovak_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("krovak", new krovak_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_KROVAK_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/labrd.hpp b/src/boost/geometry/extensions/gis/projections/proj/labrd.hpp
new file mode 100644
index 0000000..8f180d7
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/labrd.hpp
@@ -0,0 +1,231 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace labrd{
+ static const double EPS = 1.e-10;
+
+ struct par_labrd
+ {
+ double Az, kRg, p0s, A, C, Ca, Cb, Cc, Cd;
+ int rot;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_labrd_ellipsoid : public base_t_fi<base_labrd_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_labrd m_proj_parm;
+
+ inline base_labrd_ellipsoid(const Parameters& par)
+ : base_t_fi<base_labrd_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double V1, V2, ps, sinps, cosps, sinps2, cosps2, I1, I2, I3, I4, I5, I6,
+ x2, y2, t;
+
+ V1 = this->m_proj_parm.A * log( tan(FORTPI + .5 * lp_lat) );
+ t = this->m_par.e * sin(lp_lat);
+ V2 = .5 * this->m_par.e * this->m_proj_parm.A * log ((1. + t)/(1. - t));
+ ps = 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - FORTPI);
+ I1 = ps - this->m_proj_parm.p0s;
+ cosps = cos(ps); cosps2 = cosps * cosps;
+ sinps = sin(ps); sinps2 = sinps * sinps;
+ I4 = this->m_proj_parm.A * cosps;
+ I2 = .5 * this->m_proj_parm.A * I4 * sinps;
+ I3 = I2 * this->m_proj_parm.A * this->m_proj_parm.A * (5. * cosps2 - sinps2) / 12.;
+ I6 = I4 * this->m_proj_parm.A * this->m_proj_parm.A;
+ I5 = I6 * (cosps2 - sinps2) / 6.;
+ I6 *= this->m_proj_parm.A * this->m_proj_parm.A *
+ (5. * cosps2 * cosps2 + sinps2 * (sinps2 - 18. * cosps2)) / 120.;
+ t = lp_lon * lp_lon;
+ xy_x = this->m_proj_parm.kRg * lp_lon * (I4 + t * (I5 + t * I6));
+ xy_y = this->m_proj_parm.kRg * (I1 + t * (I2 + t * I3));
+ x2 = xy_x * xy_x;
+ y2 = xy_y * xy_y;
+ V1 = 3. * xy_x * y2 - xy_x * x2;
+ V2 = xy_y * y2 - 3. * x2 * xy_y;
+ xy_x += this->m_proj_parm.Ca * V1 + this->m_proj_parm.Cb * V2;
+ xy_y += this->m_proj_parm.Ca * V2 - this->m_proj_parm.Cb * V1;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double x2, y2, V1, V2, V3, V4, t, t2, ps, pe, tpe, s,
+ I7, I8, I9, I10, I11, d, Re;
+ int i;
+
+ x2 = xy_x * xy_x;
+ y2 = xy_y * xy_y;
+ V1 = 3. * xy_x * y2 - xy_x * x2;
+ V2 = xy_y * y2 - 3. * x2 * xy_y;
+ V3 = xy_x * (5. * y2 * y2 + x2 * (-10. * y2 + x2 ));
+ V4 = xy_y * (5. * x2 * x2 + y2 * (-10. * x2 + y2 ));
+ xy_x += - this->m_proj_parm.Ca * V1 - this->m_proj_parm.Cb * V2 + this->m_proj_parm.Cc * V3 + this->m_proj_parm.Cd * V4;
+ xy_y += this->m_proj_parm.Cb * V1 - this->m_proj_parm.Ca * V2 - this->m_proj_parm.Cd * V3 + this->m_proj_parm.Cc * V4;
+ ps = this->m_proj_parm.p0s + xy_y / this->m_proj_parm.kRg;
+ pe = ps + this->m_par.phi0 - this->m_proj_parm.p0s;
+ for ( i = 20; i; --i) {
+ V1 = this->m_proj_parm.A * log(tan(FORTPI + .5 * pe));
+ tpe = this->m_par.e * sin(pe);
+ V2 = .5 * this->m_par.e * this->m_proj_parm.A * log((1. + tpe)/(1. - tpe));
+ t = ps - 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - FORTPI);
+ pe += t;
+ if (fabs(t) < EPS)
+ break;
+ }
+ /*
+ if (!i) {
+ } else {
+ }
+ */
+ t = this->m_par.e * sin(pe);
+ t = 1. - t * t;
+ Re = this->m_par.one_es / ( t * sqrt(t) );
+ t = tan(ps);
+ t2 = t * t;
+ s = this->m_proj_parm.kRg * this->m_proj_parm.kRg;
+ d = Re * this->m_par.k0 * this->m_proj_parm.kRg;
+ I7 = t / (2. * d);
+ I8 = t * (5. + 3. * t2) / (24. * d * s);
+ d = cos(ps) * this->m_proj_parm.kRg * this->m_proj_parm.A;
+ I9 = 1. / d;
+ d *= s;
+ I10 = (1. + 2. * t2) / (6. * d);
+ I11 = (5. + t2 * (28. + 24. * t2)) / (120. * d * s);
+ x2 = xy_x * xy_x;
+ lp_lat = pe + x2 * (-I7 + I8 * x2);
+ lp_lon = xy_x * (I9 + x2 * (-I10 + x2 * I11));
+ }
+ };
+
+ // Laborde
+ template <typename Parameters>
+ void setup_labrd(Parameters& par, par_labrd& proj_parm)
+ {
+ double Az, sinp, R, N, t;
+ proj_parm.rot = pj_param(par.params, "bno_rot").i == 0;
+ Az = pj_param(par.params, "razi").f;
+ sinp = sin(par.phi0);
+ t = 1. - par.es * sinp * sinp;
+ N = 1. / sqrt(t);
+ R = par.one_es * N / t;
+ proj_parm.kRg = par.k0 * sqrt( N * R );
+ proj_parm.p0s = atan( sqrt(R / N) * tan(par.phi0) );
+ proj_parm.A = sinp / sin(proj_parm.p0s);
+ t = par.e * sinp;
+ proj_parm.C = .5 * par.e * proj_parm.A * log((1. + t)/(1. - t)) +
+ - proj_parm.A * log( tan(FORTPI + .5 * par.phi0))
+ + log( tan(FORTPI + .5 * proj_parm.p0s));
+ t = Az + Az;
+ proj_parm.Ca = (1. - cos(t)) * ( proj_parm.Cb = 1. / (12. * proj_parm.kRg * proj_parm.kRg) );
+ proj_parm.Cb *= sin(t);
+ proj_parm.Cc = 3. * (proj_parm.Ca * proj_parm.Ca - proj_parm.Cb * proj_parm.Cb);
+ proj_parm.Cd = 6. * proj_parm.Ca * proj_parm.Cb;
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+ }} // namespace detail::labrd
+ #endif // doxygen
+
+ /*!
+ \brief Laborde projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Special for Madagascar
+ \par Example
+ \image html ex_labrd.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct labrd_ellipsoid : public detail::labrd::base_labrd_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline labrd_ellipsoid(const Parameters& par) : detail::labrd::base_labrd_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::labrd::setup_labrd(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class labrd_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<labrd_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void labrd_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("labrd", new labrd_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LABRD_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/laea.hpp b/src/boost/geometry/extensions/gis/projections/proj/laea.hpp
new file mode 100644
index 0000000..7eb9193
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/laea.hpp
@@ -0,0 +1,391 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_qsfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_auth.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace laea{
+ static const double EPS10 = 1.e-10;
+ static const int NITER = 20;
+ static const double CONV = 1.e-10;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ struct par_laea
+ {
+ double sinb1;
+ double cosb1;
+ double xmf;
+ double ymf;
+ double mmf;
+ double qp;
+ double dd;
+ double rq;
+ double apa[APA_SIZE];
+ int mode;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_laea_ellipsoid : public base_t_fi<base_laea_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_laea m_proj_parm;
+
+ inline base_laea_ellipsoid(const Parameters& par)
+ : base_t_fi<base_laea_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0;
+
+ coslam = cos(lp_lon);
+ sinlam = sin(lp_lon);
+ sinphi = sin(lp_lat);
+ q = pj_qsfn(sinphi, this->m_par.e, this->m_par.one_es);
+ if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) {
+ sinb = q / this->m_proj_parm.qp;
+ cosb = sqrt(1. - sinb * sinb);
+ }
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ b = 1. + this->m_proj_parm.sinb1 * sinb + this->m_proj_parm.cosb1 * cosb * coslam;
+ break;
+ case EQUIT:
+ b = 1. + cosb * coslam;
+ break;
+ case N_POLE:
+ b = HALFPI + lp_lat;
+ q = this->m_proj_parm.qp - q;
+ break;
+ case S_POLE:
+ b = lp_lat - HALFPI;
+ q = this->m_proj_parm.qp + q;
+ break;
+ }
+ if (fabs(b) < EPS10) throw proj_exception();;
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ xy_y = this->m_proj_parm.ymf * ( b = sqrt(2. / b) )
+ * (this->m_proj_parm.cosb1 * sinb - this->m_proj_parm.sinb1 * cosb * coslam);
+ goto eqcon;
+ break;
+ case EQUIT:
+ xy_y = (b = sqrt(2. / (1. + cosb * coslam))) * sinb * this->m_proj_parm.ymf;
+ eqcon:
+ xy_x = this->m_proj_parm.xmf * b * cosb * sinlam;
+ break;
+ case N_POLE:
+ case S_POLE:
+ if (q >= 0.) {
+ xy_x = (b = sqrt(q)) * sinlam;
+ xy_y = coslam * (this->m_proj_parm.mode == S_POLE ? b : -b);
+ } else
+ xy_x = xy_y = 0.;
+ break;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double cCe, sCe, q, rho, ab=0.0;
+
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ case OBLIQ:
+ if ((rho = boost::math::hypot(xy_x /= this->m_proj_parm.dd, xy_y *= this->m_proj_parm.dd)) < EPS10) {
+ lp_lon = 0.;
+ lp_lat = this->m_par.phi0;
+ return;
+ }
+ cCe = cos(sCe = 2. * asin(.5 * rho / this->m_proj_parm.rq));
+ xy_x *= (sCe = sin(sCe));
+ if (this->m_proj_parm.mode == OBLIQ) {
+ q = this->m_proj_parm.qp * (ab = cCe * this->m_proj_parm.sinb1 + xy_y * sCe * this->m_proj_parm.cosb1 / rho);
+ xy_y = rho * this->m_proj_parm.cosb1 * cCe - xy_y * this->m_proj_parm.sinb1 * sCe;
+ } else {
+ q = this->m_proj_parm.qp * (ab = xy_y * sCe / rho);
+ xy_y = rho * cCe;
+ }
+ break;
+ case N_POLE:
+ xy_y = -xy_y;
+ case S_POLE:
+ if (!(q = (xy_x * xy_x + xy_y * xy_y)) ) {
+ lp_lon = 0.;
+ lp_lat = this->m_par.phi0;
+ return;
+ }
+ /*
+ q = this->m_proj_parm.qp - q;
+ */
+ ab = 1. - q / this->m_proj_parm.qp;
+ if (this->m_proj_parm.mode == S_POLE)
+ ab = - ab;
+ break;
+ }
+ lp_lon = atan2(xy_x, xy_y);
+ lp_lat = pj_authlat(asin(ab), this->m_proj_parm.apa);
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_laea_spheroid : public base_t_fi<base_laea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_laea m_proj_parm;
+
+ inline base_laea_spheroid(const Parameters& par)
+ : base_t_fi<base_laea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, cosphi, sinphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ xy_y = 1. + cosphi * coslam;
+ goto oblcon;
+ case OBLIQ:
+ xy_y = 1. + this->m_proj_parm.sinb1 * sinphi + this->m_proj_parm.cosb1 * cosphi * coslam;
+ oblcon:
+ if (xy_y <= EPS10) throw proj_exception();;
+ xy_x = (xy_y = sqrt(2. / xy_y)) * cosphi * sin(lp_lon);
+ xy_y *= this->m_proj_parm.mode == EQUIT ? sinphi :
+ this->m_proj_parm.cosb1 * sinphi - this->m_proj_parm.sinb1 * cosphi * coslam;
+ break;
+ case N_POLE:
+ coslam = -coslam;
+ case S_POLE:
+ if (fabs(lp_lat + this->m_par.phi0) < EPS10) throw proj_exception();;
+ xy_y = FORTPI - lp_lat * .5;
+ xy_y = 2. * (this->m_proj_parm.mode == S_POLE ? cos(xy_y) : sin(xy_y));
+ xy_x = xy_y * sin(lp_lon);
+ xy_y *= coslam;
+ break;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double cosz=0.0, rh, sinz=0.0;
+
+ rh = boost::math::hypot(xy_x, xy_y);
+ if ((lp_lat = rh * .5 ) > 1.) throw proj_exception();;
+ lp_lat = 2. * asin(lp_lat);
+ if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) {
+ sinz = sin(lp_lat);
+ cosz = cos(lp_lat);
+ }
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ lp_lat = fabs(rh) <= EPS10 ? 0. : asin(xy_y * sinz / rh);
+ xy_x *= sinz;
+ xy_y = cosz * rh;
+ break;
+ case OBLIQ:
+ lp_lat = fabs(rh) <= EPS10 ? this->m_par.phi0 :
+ asin(cosz * this->m_proj_parm.sinb1 + xy_y * sinz * this->m_proj_parm.cosb1 / rh);
+ xy_x *= sinz * this->m_proj_parm.cosb1;
+ xy_y = (cosz - sin(lp_lat) * this->m_proj_parm.sinb1) * rh;
+ break;
+ case N_POLE:
+ xy_y = -xy_y;
+ lp_lat = HALFPI - lp_lat;
+ break;
+ case S_POLE:
+ lp_lat -= HALFPI;
+ break;
+ }
+ lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == EQUIT || this->m_proj_parm.mode == OBLIQ)) ?
+ 0. : atan2(xy_x, xy_y);
+ }
+ };
+
+ // Lambert Azimuthal Equal Area
+ template <typename Parameters>
+ void setup_laea(Parameters& par, par_laea& proj_parm)
+ {
+ double t;
+ if (fabs((t = fabs(par.phi0)) - HALFPI) < EPS10)
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ else if (fabs(t) < EPS10)
+ proj_parm.mode = EQUIT;
+ else
+ proj_parm.mode = OBLIQ;
+ if (par.es) {
+ double sinphi;
+ par.e = sqrt(par.es);
+ proj_parm.qp = pj_qsfn(1., par.e, par.one_es);
+ proj_parm.mmf = .5 / (1. - par.es);
+ pj_authset(par.es, proj_parm.apa);
+ switch (proj_parm.mode) {
+ case N_POLE:
+ case S_POLE:
+ proj_parm.dd = 1.;
+ break;
+ case EQUIT:
+ proj_parm.dd = 1. / (proj_parm.rq = sqrt(.5 * proj_parm.qp));
+ proj_parm.xmf = 1.;
+ proj_parm.ymf = .5 * proj_parm.qp;
+ break;
+ case OBLIQ:
+ proj_parm.rq = sqrt(.5 * proj_parm.qp);
+ sinphi = sin(par.phi0);
+ proj_parm.sinb1 = pj_qsfn(sinphi, par.e, par.one_es) / proj_parm.qp;
+ proj_parm.cosb1 = sqrt(1. - proj_parm.sinb1 * proj_parm.sinb1);
+ proj_parm.dd = cos(par.phi0) / (sqrt(1. - par.es * sinphi * sinphi) *
+ proj_parm.rq * proj_parm.cosb1);
+ proj_parm.ymf = (proj_parm.xmf = proj_parm.rq) / proj_parm.dd;
+ proj_parm.xmf *= proj_parm.dd;
+ break;
+ }
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ if (proj_parm.mode == OBLIQ) {
+ proj_parm.sinb1 = sin(par.phi0);
+ proj_parm.cosb1 = cos(par.phi0);
+ }
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+ }} // namespace detail::laea
+ #endif // doxygen
+
+ /*!
+ \brief Lambert Azimuthal Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_laea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct laea_ellipsoid : public detail::laea::base_laea_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline laea_ellipsoid(const Parameters& par) : detail::laea::base_laea_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::laea::setup_laea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Lambert Azimuthal Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_laea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct laea_spheroid : public detail::laea::base_laea_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline laea_spheroid(const Parameters& par) : detail::laea::base_laea_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::laea::setup_laea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class laea_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<laea_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<laea_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void laea_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("laea", new laea_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LAEA_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/lagrng.hpp b/src/boost/geometry/extensions/gis/projections/proj/lagrng.hpp
new file mode 100644
index 0000000..24749ef
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/lagrng.hpp
@@ -0,0 +1,158 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lagrng{
+ static const double TOL = 1e-10;
+
+ struct par_lagrng
+ {
+ double hrw;
+ double rw;
+ double a1;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_lagrng_spheroid : public base_t_f<base_lagrng_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_lagrng m_proj_parm;
+
+ inline base_lagrng_spheroid(const Parameters& par)
+ : base_t_f<base_lagrng_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double v, c;
+
+ if (fabs(fabs(lp_lat) - HALFPI) < TOL) {
+ xy_x = 0;
+ xy_y = lp_lat < 0 ? -2. : 2.;
+ } else {
+ lp_lat = sin(lp_lat);
+ v = this->m_proj_parm.a1 * pow((1. + lp_lat)/(1. - lp_lat), this->m_proj_parm.hrw);
+ if ((c = 0.5 * (v + 1./v) + cos(lp_lon *= this->m_proj_parm.rw)) < TOL)
+ throw proj_exception();;
+ xy_x = 2. * sin(lp_lon) / c;
+ xy_y = (v - 1./v) / c;
+ }
+ }
+ };
+
+ // Lagrange
+ template <typename Parameters>
+ void setup_lagrng(Parameters& par, par_lagrng& proj_parm)
+ {
+ double phi1;
+ if ((proj_parm.rw = pj_param(par.params, "dW").f) <= 0) throw proj_exception(-27);
+ proj_parm.hrw = 0.5 * (proj_parm.rw = 1. / proj_parm.rw);
+ phi1 = pj_param(par.params, "rlat_1").f;
+ if (fabs(fabs(phi1 = sin(phi1)) - 1.) < TOL) throw proj_exception(-22);
+ proj_parm.a1 = pow((1. - phi1)/(1. + phi1), proj_parm.hrw);
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::lagrng
+ #endif // doxygen
+
+ /*!
+ \brief Lagrange projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ - W=
+ \par Example
+ \image html ex_lagrng.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct lagrng_spheroid : public detail::lagrng::base_lagrng_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline lagrng_spheroid(const Parameters& par) : detail::lagrng::base_lagrng_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::lagrng::setup_lagrng(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class lagrng_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<lagrng_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void lagrng_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("lagrng", new lagrng_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LAGRNG_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/larr.hpp b/src/boost/geometry/extensions/gis/projections/proj/larr.hpp
new file mode 100644
index 0000000..f851f42
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/larr.hpp
@@ -0,0 +1,134 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LARR_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LARR_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace larr{
+ static const double SIXTH = .16666666666666666;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_larr_spheroid : public base_t_f<base_larr_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_larr_spheroid(const Parameters& par)
+ : base_t_f<base_larr_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = 0.5 * lp_lon * (1. + sqrt(cos(lp_lat)));
+ xy_y = lp_lat / (cos(0.5 * lp_lat) * cos(SIXTH * lp_lon));
+ }
+ };
+
+ // Larrivee
+ template <typename Parameters>
+ void setup_larr(Parameters& par)
+ {
+ // par.fwd = s_forward;
+ // par.inv = 0;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::larr
+ #endif // doxygen
+
+ /*!
+ \brief Larrivee projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_larr.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct larr_spheroid : public detail::larr::base_larr_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline larr_spheroid(const Parameters& par) : detail::larr::base_larr_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::larr::setup_larr(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class larr_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<larr_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void larr_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("larr", new larr_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LARR_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/lask.hpp b/src/boost/geometry/extensions/gis/projections/proj/lask.hpp
new file mode 100644
index 0000000..e3c8bf0
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/lask.hpp
@@ -0,0 +1,148 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LASK_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LASK_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lask{
+ static const double a10 = 0.975534;
+ static const double a12 = -0.119161;
+ static const double a32 = -0.0143059;
+ static const double a14 = -0.0547009;
+ static const double b01 = 1.00384;
+ static const double b21 = 0.0802894;
+ static const double b03 = 0.0998909;
+ static const double b41 = 0.000199025;
+ static const double b23 = -0.0285500;
+ static const double b05 = -0.0491032;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_lask_spheroid : public base_t_f<base_lask_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_lask_spheroid(const Parameters& par)
+ : base_t_f<base_lask_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double l2, p2;
+
+ l2 = lp_lon * lp_lon;
+ p2 = lp_lat * lp_lat;
+ xy_x = lp_lon * (a10 + p2 * (a12 + l2 * a32 + p2 * a14));
+ xy_y = lp_lat * (b01 + l2 * (b21 + p2 * b23 + l2 * b41) +
+ p2 * (b03 + p2 * b05));
+ }
+ };
+
+ // Laskowski
+ template <typename Parameters>
+ void setup_lask(Parameters& par)
+ {
+ // par.fwd = s_forward;
+ // par.inv = 0;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::lask
+ #endif // doxygen
+
+ /*!
+ \brief Laskowski projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_lask.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct lask_spheroid : public detail::lask::base_lask_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline lask_spheroid(const Parameters& par) : detail::lask::base_lask_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::lask::setup_lask(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class lask_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<lask_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void lask_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("lask", new lask_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LASK_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/latlong.hpp b/src/boost/geometry/extensions/gis/projections/proj/latlong.hpp
new file mode 100644
index 0000000..6f39a5d
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/latlong.hpp
@@ -0,0 +1,282 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+#include <boost/geometry/extensions/gis/projections/epsg_traits.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace latlong{
+
+
+ /* very loosely based upon DMA code by Bradford W. Drew */
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_latlong_other : public base_t_fi<base_latlong_other<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_latlong_other(const Parameters& par)
+ : base_t_fi<base_latlong_other<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+
+ xy_x = lp_lon / this->m_par.a;
+ xy_y = lp_lat / this->m_par.a;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+
+ lp_lat = xy_y * this->m_par.a;
+ lp_lon = xy_x * this->m_par.a;
+ }
+ };
+
+ // Lat/long (Geodetic)
+ template <typename Parameters>
+ void setup_lonlat(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ // par.inv = inverse;
+ // par.fwd = forward;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ void setup_latlon(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ // par.inv = inverse;
+ // par.fwd = forward;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ void setup_latlong(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ // par.inv = inverse;
+ // par.fwd = forward;
+ }
+
+ // Lat/long (Geodetic alias)
+ template <typename Parameters>
+ void setup_longlat(Parameters& par)
+ {
+ par.is_latlong = 1;
+ par.x0 = 0.0;
+ par.y0 = 0.0;
+ // par.inv = inverse;
+ // par.fwd = forward;
+ }
+
+ }} // namespace detail::latlong
+ #endif // doxygen
+
+ /*!
+ \brief Lat/long (Geodetic) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ \par Example
+ \image html ex_lonlat.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct lonlat_other : public detail::latlong::base_latlong_other<Geographic, Cartesian, Parameters>
+ {
+ inline lonlat_other(const Parameters& par) : detail::latlong::base_latlong_other<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::latlong::setup_lonlat(this->m_par);
+ }
+ };
+
+ /*!
+ \brief Lat/long (Geodetic alias) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ \par Example
+ \image html ex_latlon.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct latlon_other : public detail::latlong::base_latlong_other<Geographic, Cartesian, Parameters>
+ {
+ inline latlon_other(const Parameters& par) : detail::latlong::base_latlong_other<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::latlong::setup_latlon(this->m_par);
+ }
+ };
+
+ /*!
+ \brief Lat/long (Geodetic alias) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ \par Example
+ \image html ex_latlong.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct latlong_other : public detail::latlong::base_latlong_other<Geographic, Cartesian, Parameters>
+ {
+ inline latlong_other(const Parameters& par) : detail::latlong::base_latlong_other<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::latlong::setup_latlong(this->m_par);
+ }
+ };
+
+ /*!
+ \brief Lat/long (Geodetic alias) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ \par Example
+ \image html ex_longlat.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct longlat_other : public detail::latlong::base_latlong_other<Geographic, Cartesian, Parameters>
+ {
+ inline longlat_other(const Parameters& par) : detail::latlong::base_latlong_other<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::latlong::setup_longlat(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class lonlat_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lonlat_other<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class latlon_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<latlon_other<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class latlong_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<latlong_other<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class longlat_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<longlat_other<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void latlong_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("lonlat", new lonlat_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("latlon", new latlon_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("latlong", new latlong_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("longlat", new longlat_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ // Create EPSG specializations
+ // (Proof of Concept, only for some)
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<4326, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef longlat_other<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=longlat +ellps=WGS84 +datum=WGS84";
+ }
+ };
+
+
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LATLONG_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/lcc.hpp b/src/boost/geometry/extensions/gis/projections/proj/lcc.hpp
new file mode 100644
index 0000000..395d46a
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/lcc.hpp
@@ -0,0 +1,249 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp>
+
+#include <boost/geometry/extensions/gis/projections/epsg_traits.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lcc{
+ static const double EPS10 = 1.e-10;
+
+ struct par_lcc
+ {
+ double phi1;
+ double phi2;
+ double n;
+ double rho0;
+ double c;
+ int ellips;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_lcc_ellipsoid : public base_t_fi<base_lcc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ mutable par_lcc m_proj_parm;
+
+ inline base_lcc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_lcc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double rho;
+ if (fabs(fabs(lp_lat) - HALFPI) < EPS10) {
+ if ((lp_lat * this->m_proj_parm.n) <= 0.) throw proj_exception();;
+ rho = 0.;
+ }
+ else
+ rho = this->m_proj_parm.c * (this->m_proj_parm.ellips ? pow(pj_tsfn(lp_lat, sin(lp_lat),
+ this->m_par.e), this->m_proj_parm.n) : pow(tan(FORTPI + .5 * lp_lat), -this->m_proj_parm.n));
+ xy_x = this->m_par.k0 * (rho * sin( lp_lon *= this->m_proj_parm.n ) );
+ xy_y = this->m_par.k0 * (this->m_proj_parm.rho0 - rho * cos(lp_lon) );
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rho;
+ xy_x /= this->m_par.k0;
+ xy_y /= this->m_par.k0;
+ if( (rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho0 - xy_y)) != 0.0) {
+ if (this->m_proj_parm.n < 0.) {
+ rho = -rho;
+ xy_x = -xy_x;
+ xy_y = -xy_y;
+ }
+ if (this->m_proj_parm.ellips) {
+ if ((lp_lat = pj_phi2(pow(rho / this->m_proj_parm.c, 1./this->m_proj_parm.n), this->m_par.e))
+ == HUGE_VAL)
+ throw proj_exception();;
+ } else
+ lp_lat = 2. * atan(pow(this->m_proj_parm.c / rho, 1./this->m_proj_parm.n)) - HALFPI;
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ } else {
+ lp_lon = 0.;
+ lp_lat = this->m_proj_parm.n > 0. ? HALFPI : - HALFPI;
+ }
+ }
+
+ #ifdef SPECIAL_FACTORS_NOT_CONVERTED
+ inline void fac(Geographic lp, Factors &fac) const
+ {
+ double rho;
+ if (fabs(fabs(lp_lat) - HALFPI) < EPS10) {
+ if ((lp_lat * this->m_proj_parm.n) <= 0.) return;
+ rho = 0.;
+ } else
+ rho = this->m_proj_parm.c * (this->m_proj_parm.ellips ? pow(pj_tsfn(lp_lat, sin(lp_lat),
+ this->m_par.e), this->m_proj_parm.n) : pow(tan(FORTPI + .5 * lp_lat), -this->m_proj_parm.n));
+ this->m_fac.code |= IS_ANAL_HK + IS_ANAL_CONV;
+ this->m_fac.k = this->m_fac.h = this->m_par.k0 * this->m_proj_parm.n * rho /
+ pj_msfn(sin(lp_lat), cos(lp_lat), this->m_par.es);
+ this->m_fac.conv = - this->m_proj_parm.n * lp_lon;
+ }
+ #endif
+ };
+
+ // Lambert Conformal Conic
+ template <typename Parameters>
+ void setup_lcc(Parameters& par, par_lcc& proj_parm)
+ {
+ double cosphi, sinphi;
+ int secant;
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ if (pj_param(par.params, "tlat_2").i)
+ proj_parm.phi2 = pj_param(par.params, "rlat_2").f;
+ else {
+ proj_parm.phi2 = proj_parm.phi1;
+ if (!pj_param(par.params, "tlat_0").i)
+ par.phi0 = proj_parm.phi1;
+ }
+ if (fabs(proj_parm.phi1 + proj_parm.phi2) < EPS10) throw proj_exception(-21);
+ proj_parm.n = sinphi = sin(proj_parm.phi1);
+ cosphi = cos(proj_parm.phi1);
+ secant = fabs(proj_parm.phi1 - proj_parm.phi2) >= EPS10;
+ if( (proj_parm.ellips = (par.es != 0.)) ) {
+ double ml1, m1;
+ par.e = sqrt(par.es);
+ m1 = pj_msfn(sinphi, cosphi, par.es);
+ ml1 = pj_tsfn(proj_parm.phi1, sinphi, par.e);
+ if (secant) { /* secant cone */
+ proj_parm.n = log(m1 /
+ pj_msfn(sinphi = sin(proj_parm.phi2), cos(proj_parm.phi2), par.es));
+ proj_parm.n /= log(ml1 / pj_tsfn(proj_parm.phi2, sinphi, par.e));
+ }
+ proj_parm.c = (proj_parm.rho0 = m1 * pow(ml1, -proj_parm.n) / proj_parm.n);
+ proj_parm.rho0 *= (fabs(fabs(par.phi0) - HALFPI) < EPS10) ? 0. :
+ pow(pj_tsfn(par.phi0, sin(par.phi0), par.e), proj_parm.n);
+ } else {
+ if (secant)
+ proj_parm.n = log(cosphi / cos(proj_parm.phi2)) /
+ log(tan(FORTPI + .5 * proj_parm.phi2) /
+ tan(FORTPI + .5 * proj_parm.phi1));
+ proj_parm.c = cosphi * pow(tan(FORTPI + .5 * proj_parm.phi1), proj_parm.n) / proj_parm.n;
+ proj_parm.rho0 = (fabs(fabs(par.phi0) - HALFPI) < EPS10) ? 0. :
+ proj_parm.c * pow(tan(FORTPI + .5 * par.phi0), -proj_parm.n);
+ }
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ // par.spc = fac;
+ }
+
+ }} // namespace detail::lcc
+ #endif // doxygen
+
+ /*!
+ \brief Lambert Conformal Conic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ - lat_1= and lat_2= or lat_0
+ \par Example
+ \image html ex_lcc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct lcc_ellipsoid : public detail::lcc::base_lcc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline lcc_ellipsoid(const Parameters& par) : detail::lcc::base_lcc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::lcc::setup_lcc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class lcc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lcc_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void lcc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("lcc", new lcc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ // Create EPSG specializations
+ // (Proof of Concept, only for some)
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2805, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef lcc_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=lcc +lat_1=42.68333333333333 +lat_2=41.71666666666667 +lat_0=41 +lon_0=-71.5 +x_0=200000 +y_0=750000 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LCC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/lcca.hpp b/src/boost/geometry/extensions/gis/projections/proj/lcca.hpp
new file mode 100644
index 0000000..30d05f5
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/lcca.hpp
@@ -0,0 +1,191 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lcca{
+ static const int MAX_ITER = 10;
+ static const double DEL_TOL = 1e-12;
+
+ struct par_lcca
+ {
+ double en[EN_SIZE];
+ double r0, l, M0;
+ double C;
+ };
+
+
+ inline double /* func to compute dr */
+ fS(double S, double C) {
+ return(S * ( 1. + S * S * C));
+ }
+ inline double /* deriv of fs */
+ fSp(double S, double C) {
+ return(1. + 3.* S * S * C);
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_lcca_ellipsoid : public base_t_fi<base_lcca_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_lcca m_proj_parm;
+
+ inline base_lcca_ellipsoid(const Parameters& par)
+ : base_t_fi<base_lcca_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double S, r, dr;
+
+ S = pj_mlfn(lp_lat, sin(lp_lat), cos(lp_lat), this->m_proj_parm.en) - this->m_proj_parm.M0;
+ dr = fS(S, this->m_proj_parm.C);
+ r = this->m_proj_parm.r0 - dr;
+ xy_x = this->m_par.k0 * (r * sin( lp_lon *= this->m_proj_parm.l ) );
+ xy_y = this->m_par.k0 * (this->m_proj_parm.r0 - r * cos(lp_lon) );
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double theta, dr, S, dif;
+ int i;
+
+ xy_x /= this->m_par.k0;
+ xy_y /= this->m_par.k0;
+ theta = atan2(xy_x , this->m_proj_parm.r0 - xy_y);
+ dr = xy_y - xy_x * tan(0.5 * theta);
+ lp_lon = theta / this->m_proj_parm.l;
+ S = dr;
+ for (i = MAX_ITER; i ; --i) {
+ S -= (dif = (fS(S, this->m_proj_parm.C) - dr) / fSp(S, this->m_proj_parm.C));
+ if (fabs(dif) < DEL_TOL) break;
+ }
+ if (!i) throw proj_exception();
+ lp_lat = pj_inv_mlfn(S + this->m_proj_parm.M0, this->m_par.es, this->m_proj_parm.en);
+ }
+ };
+
+ // Lambert Conformal Conic Alternative
+ template <typename Parameters>
+ void setup_lcca(Parameters& par, par_lcca& proj_parm)
+ {
+ double s2p0, N0, R0, tan0, tan20;
+ pj_enfn(par.es, proj_parm.en);
+ if (!pj_param(par.params, "tlat_0").i) throw proj_exception(50);
+ if (par.phi0 == 0.) throw proj_exception(51);
+ proj_parm.l = sin(par.phi0);
+ proj_parm.M0 = pj_mlfn(par.phi0, proj_parm.l, cos(par.phi0), proj_parm.en);
+ s2p0 = proj_parm.l * proj_parm.l;
+ R0 = 1. / (1. - par.es * s2p0);
+ N0 = sqrt(R0);
+ R0 *= par.one_es * N0;
+ tan0 = tan(par.phi0);
+ tan20 = tan0 * tan0;
+ proj_parm.r0 = N0 / tan0;
+ proj_parm.C = 1. / (6. * R0 * N0);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+ }} // namespace detail::lcca
+ #endif // doxygen
+
+ /*!
+ \brief Lambert Conformal Conic Alternative projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ - lat_0=
+ \par Example
+ \image html ex_lcca.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct lcca_ellipsoid : public detail::lcca::base_lcca_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline lcca_ellipsoid(const Parameters& par) : detail::lcca::base_lcca_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::lcca::setup_lcca(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class lcca_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lcca_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void lcca_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("lcca", new lcca_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LCCA_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/loxim.hpp b/src/boost/geometry/extensions/gis/projections/proj/loxim.hpp
new file mode 100644
index 0000000..3c5249e
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/loxim.hpp
@@ -0,0 +1,164 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace loxim{
+ static const double EPS = 1e-8;
+
+ struct par_loxim
+ {
+ double phi1;
+ double cosphi1;
+ double tanphi1;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_loxim_spheroid : public base_t_fi<base_loxim_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_loxim m_proj_parm;
+
+ inline base_loxim_spheroid(const Parameters& par)
+ : base_t_fi<base_loxim_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_y = lp_lat - this->m_proj_parm.phi1;
+ if (fabs(xy_y) < EPS)
+ xy_x = lp_lon * this->m_proj_parm.cosphi1;
+ else {
+ xy_x = FORTPI + 0.5 * lp_lat;
+ if (fabs(xy_x) < EPS || fabs(fabs(xy_x) - HALFPI) < EPS)
+ xy_x = 0.;
+ else
+ xy_x = lp_lon * xy_y / log( tan(xy_x) / this->m_proj_parm.tanphi1 );
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y + this->m_proj_parm.phi1;
+ if (fabs(xy_y) < EPS)
+ lp_lon = xy_x / this->m_proj_parm.cosphi1;
+ else
+ if (fabs( lp_lon = FORTPI + 0.5 * lp_lat ) < EPS ||
+ fabs(fabs(lp_lon) - HALFPI) < EPS)
+ lp_lon = 0.;
+ else
+ lp_lon = xy_x * log( tan(lp_lon) / this->m_proj_parm.tanphi1 ) / xy_y ;
+ }
+ };
+
+ // Loximuthal
+ template <typename Parameters>
+ void setup_loxim(Parameters& par, par_loxim& proj_parm)
+ {
+ proj_parm.phi1 = pj_param(par.params, "rlat_1").f;
+ if ((proj_parm.cosphi1 = cos(proj_parm.phi1)) < EPS) throw proj_exception(-22);
+ proj_parm.tanphi1 = tan(FORTPI + 0.5 * proj_parm.phi1);
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::loxim
+ #endif // doxygen
+
+ /*!
+ \brief Loximuthal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_loxim.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct loxim_spheroid : public detail::loxim::base_loxim_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline loxim_spheroid(const Parameters& par) : detail::loxim::base_loxim_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::loxim::setup_loxim(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class loxim_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<loxim_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void loxim_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("loxim", new loxim_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LOXIM_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/lsat.hpp b/src/boost/geometry/extensions/gis/projections/proj/lsat.hpp
new file mode 100644
index 0000000..7b6f8c2
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/lsat.hpp
@@ -0,0 +1,299 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace lsat{
+ static const double TOL = 1e-7;
+ static const double PI_HALFPI = 4.71238898038468985766;
+ static const double TWOPI_HALFPI = 7.85398163397448309610;
+
+ struct par_lsat
+ {
+ double a2, a4, b, c1, c3;
+ double q, t, u, w, p22, sa, ca, xj, rlm, rlm2;
+ };
+ /* based upon Snyder and Linck, USGS-NMD */
+ template <typename Parameters>
+ inline void
+ seraz0(double lam, double mult, Parameters& par, par_lsat& proj_parm) {
+ double sdsq, h, s, fc, sd, sq, d__1;
+
+ lam *= DEG_TO_RAD;
+ sd = sin(lam);
+ sdsq = sd * sd;
+ s = proj_parm.p22 * proj_parm.sa * cos(lam) * sqrt((1. + proj_parm.t * sdsq) / ((
+ 1. + proj_parm.w * sdsq) * (1. + proj_parm.q * sdsq)));
+ d__1 = 1. + proj_parm.q * sdsq;
+ h = sqrt((1. + proj_parm.q * sdsq) / (1. + proj_parm.w * sdsq)) * ((1. +
+ proj_parm.w * sdsq) / (d__1 * d__1) - proj_parm.p22 * proj_parm.ca);
+ sq = sqrt(proj_parm.xj * proj_parm.xj + s * s);
+ proj_parm.b += fc = mult * (h * proj_parm.xj - s * s) / sq;
+ proj_parm.a2 += fc * cos(lam + lam);
+ proj_parm.a4 += fc * cos(lam * 4.);
+ fc = mult * s * (h + proj_parm.xj) / sq;
+ proj_parm.c1 += fc * cos(lam);
+ proj_parm.c3 += fc * cos(lam * 3.);
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_lsat_ellipsoid : public base_t_fi<base_lsat_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_lsat m_proj_parm;
+
+ inline base_lsat_ellipsoid(const Parameters& par)
+ : base_t_fi<base_lsat_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ int l, nn;
+ double lamt, xlam, sdsq, c, d, s, lamdp, phidp, lampp, tanph,
+ lamtp, cl, sd, sp, fac, sav, tanphi;
+
+ if (lp_lat > HALFPI)
+ lp_lat = HALFPI;
+ else if (lp_lat < -HALFPI)
+ lp_lat = -HALFPI;
+ lampp = lp_lat >= 0. ? HALFPI : PI_HALFPI;
+ tanphi = tan(lp_lat);
+ for (nn = 0;;) {
+ sav = lampp;
+ lamtp = lp_lon + this->m_proj_parm.p22 * lampp;
+ cl = cos(lamtp);
+ if (fabs(cl) < TOL)
+ lamtp -= TOL;
+ fac = lampp - sin(lampp) * (cl < 0. ? -HALFPI : HALFPI);
+ for (l = 50; l; --l) {
+ lamt = lp_lon + this->m_proj_parm.p22 * sav;
+ if (fabs(c = cos(lamt)) < TOL)
+ lamt -= TOL;
+ xlam = (this->m_par.one_es * tanphi * this->m_proj_parm.sa + sin(lamt) * this->m_proj_parm.ca) / c;
+ lamdp = atan(xlam) + fac;
+ if (fabs(fabs(sav) - fabs(lamdp)) < TOL)
+ break;
+ sav = lamdp;
+ }
+ if (!l || ++nn >= 3 || (lamdp > this->m_proj_parm.rlm && lamdp < this->m_proj_parm.rlm2))
+ break;
+ if (lamdp <= this->m_proj_parm.rlm)
+ lampp = TWOPI_HALFPI;
+ else if (lamdp >= this->m_proj_parm.rlm2)
+ lampp = HALFPI;
+ }
+ if (l) {
+ sp = sin(lp_lat);
+ phidp = aasin((this->m_par.one_es * this->m_proj_parm.ca * sp - this->m_proj_parm.sa * cos(lp_lat) *
+ sin(lamt)) / sqrt(1. - this->m_par.es * sp * sp));
+ tanph = log(tan(FORTPI + .5 * phidp));
+ sd = sin(lamdp);
+ sdsq = sd * sd;
+ s = this->m_proj_parm.p22 * this->m_proj_parm.sa * cos(lamdp) * sqrt((1. + this->m_proj_parm.t * sdsq)
+ / ((1. + this->m_proj_parm.w * sdsq) * (1. + this->m_proj_parm.q * sdsq)));
+ d = sqrt(this->m_proj_parm.xj * this->m_proj_parm.xj + s * s);
+ xy_x = this->m_proj_parm.b * lamdp + this->m_proj_parm.a2 * sin(2. * lamdp) + this->m_proj_parm.a4 *
+ sin(lamdp * 4.) - tanph * s / d;
+ xy_y = this->m_proj_parm.c1 * sd + this->m_proj_parm.c3 * sin(lamdp * 3.) + tanph * this->m_proj_parm.xj / d;
+ } else
+ xy_x = xy_y = HUGE_VAL;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ int nn;
+ double lamt, sdsq, s, lamdp, phidp, sppsq, dd, sd, sl, fac, scl, sav, spp;
+
+ lamdp = xy_x / this->m_proj_parm.b;
+ nn = 50;
+ do {
+ sav = lamdp;
+ sd = sin(lamdp);
+ sdsq = sd * sd;
+ s = this->m_proj_parm.p22 * this->m_proj_parm.sa * cos(lamdp) * sqrt((1. + this->m_proj_parm.t * sdsq)
+ / ((1. + this->m_proj_parm.w * sdsq) * (1. + this->m_proj_parm.q * sdsq)));
+ lamdp = xy_x + xy_y * s / this->m_proj_parm.xj - this->m_proj_parm.a2 * sin(
+ 2. * lamdp) - this->m_proj_parm.a4 * sin(lamdp * 4.) - s / this->m_proj_parm.xj * (
+ this->m_proj_parm.c1 * sin(lamdp) + this->m_proj_parm.c3 * sin(lamdp * 3.));
+ lamdp /= this->m_proj_parm.b;
+ } while (fabs(lamdp - sav) >= TOL && --nn);
+ sl = sin(lamdp);
+ fac = exp(sqrt(1. + s * s / this->m_proj_parm.xj / this->m_proj_parm.xj) * (xy_y -
+ this->m_proj_parm.c1 * sl - this->m_proj_parm.c3 * sin(lamdp * 3.)));
+ phidp = 2. * (atan(fac) - FORTPI);
+ dd = sl * sl;
+ if (fabs(cos(lamdp)) < TOL)
+ lamdp -= TOL;
+ spp = sin(phidp);
+ sppsq = spp * spp;
+ lamt = atan(((1. - sppsq * this->m_par.rone_es) * tan(lamdp) *
+ this->m_proj_parm.ca - spp * this->m_proj_parm.sa * sqrt((1. + this->m_proj_parm.q * dd) * (
+ 1. - sppsq) - sppsq * this->m_proj_parm.u) / cos(lamdp)) / (1. - sppsq
+ * (1. + this->m_proj_parm.u)));
+ sl = lamt >= 0. ? 1. : -1.;
+ scl = cos(lamdp) >= 0. ? 1. : -1;
+ lamt -= HALFPI * (1. - scl) * sl;
+ lp_lon = lamt - this->m_proj_parm.p22 * lamdp;
+ if (fabs(this->m_proj_parm.sa) < TOL)
+ lp_lat = aasin(spp / sqrt(this->m_par.one_es * this->m_par.one_es + this->m_par.es * sppsq));
+ else
+ lp_lat = atan((tan(lamdp) * cos(lamt) - this->m_proj_parm.ca * sin(lamt)) /
+ (this->m_par.one_es * this->m_proj_parm.sa));
+ }
+ };
+
+ // Space oblique for LANDSAT
+ template <typename Parameters>
+ void setup_lsat(Parameters& par, par_lsat& proj_parm)
+ {
+ int land, path;
+ double lam, alf, esc, ess;
+ land = pj_param(par.params, "ilsat").i;
+ if (land <= 0 || land > 5) throw proj_exception(-28);
+ path = pj_param(par.params, "ipath").i;
+ if (path <= 0 || path > (land <= 3 ? 251 : 233)) throw proj_exception(-29);
+ if (land <= 3) {
+ par.lam0 = DEG_TO_RAD * 128.87 - TWOPI / 251. * path;
+ proj_parm.p22 = 103.2669323;
+ alf = DEG_TO_RAD * 99.092;
+ } else {
+ par.lam0 = DEG_TO_RAD * 129.3 - TWOPI / 233. * path;
+ proj_parm.p22 = 98.8841202;
+ alf = DEG_TO_RAD * 98.2;
+ }
+ proj_parm.p22 /= 1440.;
+ proj_parm.sa = sin(alf);
+ proj_parm.ca = cos(alf);
+ if (fabs(proj_parm.ca) < 1e-9)
+ proj_parm.ca = 1e-9;
+ esc = par.es * proj_parm.ca * proj_parm.ca;
+ ess = par.es * proj_parm.sa * proj_parm.sa;
+ proj_parm.w = (1. - esc) * par.rone_es;
+ proj_parm.w = proj_parm.w * proj_parm.w - 1.;
+ proj_parm.q = ess * par.rone_es;
+ proj_parm.t = ess * (2. - par.es) * par.rone_es * par.rone_es;
+ proj_parm.u = esc * par.rone_es;
+ proj_parm.xj = par.one_es * par.one_es * par.one_es;
+ proj_parm.rlm = PI * (1. / 248. + .5161290322580645);
+ proj_parm.rlm2 = proj_parm.rlm + TWOPI;
+ proj_parm.a2 = proj_parm.a4 = proj_parm.b = proj_parm.c1 = proj_parm.c3 = 0.;
+ seraz0(0., 1., par, proj_parm);
+ for (lam = 9.;
+ lam <= 81.0001;
+ lam += 18.)
+ seraz0(lam, 4., par, proj_parm);
+ for (lam = 18;
+ lam <= 72.0001;
+ lam += 18.)
+ seraz0(lam, 2., par, proj_parm);
+ seraz0(90., 1., par, proj_parm);
+ proj_parm.a2 /= 30.;
+ proj_parm.a4 /= 60.;
+ proj_parm.b /= 30.;
+ proj_parm.c1 /= 15.;
+ proj_parm.c3 /= 45.;
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+ }} // namespace detail::lsat
+ #endif // doxygen
+
+ /*!
+ \brief Space oblique for LANDSAT projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ - lsat= path=
+ \par Example
+ \image html ex_lsat.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct lsat_ellipsoid : public detail::lsat::base_lsat_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline lsat_ellipsoid(const Parameters& par) : detail::lsat::base_lsat_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::lsat::setup_lsat(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class lsat_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lsat_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void lsat_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("lsat", new lsat_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_LSAT_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/mbt_fps.hpp b/src/boost/geometry/extensions/gis/projections/proj/mbt_fps.hpp
new file mode 100644
index 0000000..391dd6b
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/mbt_fps.hpp
@@ -0,0 +1,161 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace mbt_fps{
+ static const int MAX_ITER = 10;
+ static const double LOOP_TOL = 1e-7;
+ static const double C1 = 0.45503;
+ static const double C2 = 1.36509;
+ static const double C3 = 1.41546;
+ static const double C_x = 0.22248;
+ static const double C_y = 1.44492;
+ static const double C1_2 = 0.33333333333333333333333333;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_mbt_fps_spheroid : public base_t_fi<base_mbt_fps_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_mbt_fps_spheroid(const Parameters& par)
+ : base_t_fi<base_mbt_fps_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double k, V, t;
+ int i;
+
+ k = C3 * sin(lp_lat);
+ for (i = MAX_ITER; i ; --i) {
+ t = lp_lat / C2;
+ lp_lat -= V = (C1 * sin(t) + sin(lp_lat) - k) /
+ (C1_2 * cos(t) + cos(lp_lat));
+ if (fabs(V) < LOOP_TOL)
+ break;
+ }
+ t = lp_lat / C2;
+ xy_x = C_x * lp_lon * (1. + 3. * cos(lp_lat)/cos(t) );
+ xy_y = C_y * sin(t);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double t;
+
+ lp_lat = C2 * (t = aasin(xy_y / C_y));
+ lp_lon = xy_x / (C_x * (1. + 3. * cos(lp_lat)/cos(t)));
+ lp_lat = aasin((C1 * sin(t) + sin(lp_lat)) / C3);
+ }
+ };
+
+ // McBryde-Thomas Flat-Pole Sine (No. 2)
+ template <typename Parameters>
+ void setup_mbt_fps(Parameters& par)
+ {
+ par.es = 0;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::mbt_fps
+ #endif // doxygen
+
+ /*!
+ \brief McBryde-Thomas Flat-Pole Sine (No. 2) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_mbt_fps.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct mbt_fps_spheroid : public detail::mbt_fps::base_mbt_fps_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline mbt_fps_spheroid(const Parameters& par) : detail::mbt_fps::base_mbt_fps_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mbt_fps::setup_mbt_fps(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class mbt_fps_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<mbt_fps_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void mbt_fps_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("mbt_fps", new mbt_fps_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MBT_FPS_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/mbtfpp.hpp b/src/boost/geometry/extensions/gis/projections/proj/mbtfpp.hpp
new file mode 100644
index 0000000..b543997
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/mbtfpp.hpp
@@ -0,0 +1,155 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace mbtfpp{
+ static const double CS = .95257934441568037152;
+ static const double FXC = .92582009977255146156;
+ static const double FYC = 3.40168025708304504493;
+ static const double C23 = .66666666666666666666;
+ static const double C13 = .33333333333333333333;
+ static const double ONEEPS = 1.0000001;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_mbtfpp_spheroid : public base_t_fi<base_mbtfpp_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_mbtfpp_spheroid(const Parameters& par)
+ : base_t_fi<base_mbtfpp_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat = asin(CS * sin(lp_lat));
+ xy_x = FXC * lp_lon * (2. * cos(C23 * lp_lat) - 1.);
+ xy_y = FYC * sin(C13 * lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / FYC;
+ if (fabs(lp_lat) >= 1.) {
+ if (fabs(lp_lat) > ONEEPS) throw proj_exception();
+ else lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI;
+ } else
+ lp_lat = asin(lp_lat);
+ lp_lon = xy_x / ( FXC * (2. * cos(C23 * (lp_lat *= 3.)) - 1.) );
+ if (fabs(lp_lat = sin(lp_lat) / CS) >= 1.) {
+ if (fabs(lp_lat) > ONEEPS) throw proj_exception();
+ else lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI;
+ } else
+ lp_lat = asin(lp_lat);
+ }
+ };
+
+ // McBride-Thomas Flat-Polar Parabolic
+ template <typename Parameters>
+ void setup_mbtfpp(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::mbtfpp
+ #endif // doxygen
+
+ /*!
+ \brief McBride-Thomas Flat-Polar Parabolic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_mbtfpp.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct mbtfpp_spheroid : public detail::mbtfpp::base_mbtfpp_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline mbtfpp_spheroid(const Parameters& par) : detail::mbtfpp::base_mbtfpp_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mbtfpp::setup_mbtfpp(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class mbtfpp_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<mbtfpp_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void mbtfpp_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("mbtfpp", new mbtfpp_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MBTFPP_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/mbtfpq.hpp b/src/boost/geometry/extensions/gis/projections/proj/mbtfpq.hpp
new file mode 100644
index 0000000..6bdc861
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/mbtfpq.hpp
@@ -0,0 +1,170 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace mbtfpq{
+ static const int NITER = 20;
+ static const double EPS = 1e-7;
+ static const double ONETOL = 1.000001;
+ static const double C = 1.70710678118654752440;
+ static const double RC = 0.58578643762690495119;
+ static const double FYC = 1.87475828462269495505;
+ static const double RYC = 0.53340209679417701685;
+ static const double FXC = 0.31245971410378249250;
+ static const double RXC = 3.20041258076506210122;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_mbtfpq_spheroid : public base_t_fi<base_mbtfpq_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_mbtfpq_spheroid(const Parameters& par)
+ : base_t_fi<base_mbtfpq_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double th1, c;
+ int i;
+
+ c = C * sin(lp_lat);
+ for (i = NITER; i; --i) {
+ lp_lat -= th1 = (sin(.5*lp_lat) + sin(lp_lat) - c) /
+ (.5*cos(.5*lp_lat) + cos(lp_lat));
+ if (fabs(th1) < EPS) break;
+ }
+ xy_x = FXC * lp_lon * (1.0 + 2. * cos(lp_lat)/cos(0.5 * lp_lat));
+ xy_y = FYC * sin(0.5 * lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double t;
+
+ lp_lat = RYC * xy_y;
+ if (fabs(lp_lat) > 1.) {
+ if (fabs(lp_lat) > ONETOL) throw proj_exception();
+ else if (lp_lat < 0.) { t = -1.; lp_lat = -PI; }
+ else { t = 1.; lp_lat = PI; }
+ } else
+ lp_lat = 2. * asin(t = lp_lat);
+ lp_lon = RXC * xy_x / (1. + 2. * cos(lp_lat)/cos(0.5 * lp_lat));
+ lp_lat = RC * (t + sin(lp_lat));
+ if (fabs(lp_lat) > 1.)
+ if (fabs(lp_lat) > ONETOL) throw proj_exception();
+ else lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ else
+ lp_lat = asin(lp_lat);
+ }
+ };
+
+ // McBryde-Thomas Flat-Polar Quartic
+ template <typename Parameters>
+ void setup_mbtfpq(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::mbtfpq
+ #endif // doxygen
+
+ /*!
+ \brief McBryde-Thomas Flat-Polar Quartic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_mbtfpq.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct mbtfpq_spheroid : public detail::mbtfpq::base_mbtfpq_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline mbtfpq_spheroid(const Parameters& par) : detail::mbtfpq::base_mbtfpq_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mbtfpq::setup_mbtfpq(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class mbtfpq_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<mbtfpq_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void mbtfpq_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("mbtfpq", new mbtfpq_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MBTFPQ_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/merc.hpp b/src/boost/geometry/extensions/gis/projections/proj/merc.hpp
new file mode 100644
index 0000000..f82fec0
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/merc.hpp
@@ -0,0 +1,213 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_MERC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_MERC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace merc{
+ static const double EPS10 = 1.e-10;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_merc_ellipsoid : public base_t_fi<base_merc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_merc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_merc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) throw proj_exception();;
+ xy_x = this->m_par.k0 * lp_lon;
+ xy_y = - this->m_par.k0 * log(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ if ((lp_lat = pj_phi2(exp(- xy_y / this->m_par.k0), this->m_par.e)) == HUGE_VAL) throw proj_exception();;
+ lp_lon = xy_x / this->m_par.k0;
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_merc_spheroid : public base_t_fi<base_merc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_merc_spheroid(const Parameters& par)
+ : base_t_fi<base_merc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (fabs(fabs(lp_lat) - HALFPI) <= EPS10) throw proj_exception();;
+ xy_x = this->m_par.k0 * lp_lon;
+ xy_y = this->m_par.k0 * log(tan(FORTPI + .5 * lp_lat));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = HALFPI - 2. * atan(exp(-xy_y / this->m_par.k0));
+ lp_lon = xy_x / this->m_par.k0;
+ }
+ };
+
+ // Mercator
+ template <typename Parameters>
+ void setup_merc(Parameters& par)
+ {
+ double phits=0.0;
+ int is_phits;
+ if( (is_phits = pj_param(par.params, "tlat_ts").i) ) {
+ phits = fabs(pj_param(par.params, "rlat_ts").f);
+ if (phits >= HALFPI) throw proj_exception(-24);
+ }
+ if (par.es) { /* ellipsoid */
+ if (is_phits)
+ par.k0 = pj_msfn(sin(phits), cos(phits), par.es);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else { /* sphere */
+ if (is_phits)
+ par.k0 = cos(phits);
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+ }} // namespace detail::merc
+ #endif // doxygen
+
+ /*!
+ \brief Mercator projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ - lat_ts=
+ \par Example
+ \image html ex_merc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct merc_ellipsoid : public detail::merc::base_merc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline merc_ellipsoid(const Parameters& par) : detail::merc::base_merc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::merc::setup_merc(this->m_par);
+ }
+ };
+
+ /*!
+ \brief Mercator projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ - lat_ts=
+ \par Example
+ \image html ex_merc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct merc_spheroid : public detail::merc::base_merc_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline merc_spheroid(const Parameters& par) : detail::merc::base_merc_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::merc::setup_merc(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class merc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<merc_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<merc_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void merc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("merc", new merc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MERC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/mill.hpp b/src/boost/geometry/extensions/gis/projections/proj/mill.hpp
new file mode 100644
index 0000000..d7ecdd4
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/mill.hpp
@@ -0,0 +1,138 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_MILL_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_MILL_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace mill{
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_mill_spheroid : public base_t_fi<base_mill_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_mill_spheroid(const Parameters& par)
+ : base_t_fi<base_mill_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = lp_lon;
+ xy_y = log(tan(FORTPI + lp_lat * .4)) * 1.25;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lon = xy_x;
+ lp_lat = 2.5 * (atan(exp(.8 * xy_y)) - FORTPI);
+ }
+ };
+
+ // Miller Cylindrical
+ template <typename Parameters>
+ void setup_mill(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::mill
+ #endif // doxygen
+
+ /*!
+ \brief Miller Cylindrical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_mill.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct mill_spheroid : public detail::mill::base_mill_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline mill_spheroid(const Parameters& par) : detail::mill::base_mill_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mill::setup_mill(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class mill_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<mill_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void mill_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("mill", new mill_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MILL_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/mod_ster.hpp b/src/boost/geometry/extensions/gis/projections/proj/mod_ster.hpp
new file mode 100644
index 0000000..fe90b41
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/mod_ster.hpp
@@ -0,0 +1,474 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_zpoly1.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace mod_ster{
+ static const double EPSLN = 1e-10;
+
+ struct par_mod_ster
+ {
+ COMPLEX *zcoeff;
+ double cchio, schio;
+ int n;
+ };
+ /* based upon Snyder and Linck, USGS-NMD */
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_mod_ster_ellipsoid : public base_t_fi<base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_mod_ster m_proj_parm;
+
+ inline base_mod_ster_ellipsoid(const Parameters& par)
+ : base_t_fi<base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double sinlon, coslon, esphi, chi, schi, cchi, s;
+ COMPLEX p;
+
+ sinlon = sin(lp_lon);
+ coslon = cos(lp_lon);
+ esphi = this->m_par.e * sin(lp_lat);
+ chi = 2. * atan(tan((HALFPI + lp_lat) * .5) *
+ pow((1. - esphi) / (1. + esphi), this->m_par.e * .5)) - HALFPI;
+ schi = sin(chi);
+ cchi = cos(chi);
+ s = 2. / (1. + this->m_proj_parm.schio * schi + this->m_proj_parm.cchio * cchi * coslon);
+ p.r = s * cchi * sinlon;
+ p.i = s * (this->m_proj_parm.cchio * schi - this->m_proj_parm.schio * cchi * coslon);
+ p = pj_zpoly1(p, this->m_proj_parm.zcoeff, this->m_proj_parm.n);
+ xy_x = p.r;
+ xy_y = p.i;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ int nn;
+ COMPLEX p, fxy, fpxy, dp;
+ double den, rh = 0, z, sinz = 0, cosz = 0, chi, phi = 0, dphi, esphi;
+
+ p.r = xy_x;
+ p.i = xy_y;
+ for (nn = 20; nn ;--nn) {
+ fxy = pj_zpolyd1(p, this->m_proj_parm.zcoeff, this->m_proj_parm.n, &fpxy);
+ fxy.r -= xy_x;
+ fxy.i -= xy_y;
+ den = fpxy.r * fpxy.r + fpxy.i * fpxy.i;
+ dp.r = -(fxy.r * fpxy.r + fxy.i * fpxy.i) / den;
+ dp.i = -(fxy.i * fpxy.r - fxy.r * fpxy.i) / den;
+ p.r += dp.r;
+ p.i += dp.i;
+ if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN)
+ break;
+ }
+ if (nn) {
+ rh = boost::math::hypot(p.r, p.i);
+ z = 2. * atan(.5 * rh);
+ sinz = sin(z);
+ cosz = cos(z);
+ lp_lon = this->m_par.lam0;
+ if (fabs(rh) <= EPSLN) {
+ lp_lat = this->m_par.phi0;
+ return;
+ }
+ chi = aasin(cosz * this->m_proj_parm.schio + p.i * sinz * this->m_proj_parm.cchio / rh);
+ phi = chi;
+ for (nn = 20; nn ;--nn) {
+ esphi = this->m_par.e * sin(phi);
+ dphi = 2. * atan(tan((HALFPI + chi) * .5) *
+ pow((1. + esphi) / (1. - esphi), this->m_par.e * .5)) - HALFPI - phi;
+ phi += dphi;
+ if (fabs(dphi) <= EPSLN)
+ break;
+ }
+ }
+ if (nn) {
+ lp_lat = phi;
+ lp_lon = atan2(p.r * sinz, rh * this->m_proj_parm.cchio * cosz - p.i *
+ this->m_proj_parm.schio * sinz);
+ } else
+ lp_lon = lp_lat = HUGE_VAL;
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_mod_ster& proj_parm) /* general initialization */
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ double esphi, chio;
+ if (par.es) {
+ esphi = par.e * sin(par.phi0);
+ chio = 2. * atan(tan((HALFPI + par.phi0) * .5) *
+ pow((1. - esphi) / (1. + esphi), par.e * .5)) - HALFPI;
+ } else
+ chio = par.phi0;
+ proj_parm.schio = sin(chio);
+ proj_parm.cchio = cos(chio);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+
+ // Miller Oblated Stereographic
+ template <typename Parameters>
+ void setup_mil_os(Parameters& par, par_mod_ster& proj_parm)
+ {
+ static COMPLEX /* Miller Oblated Stereographic */
+ AB[] = {
+ {0.924500, 0.},
+ {0., 0.},
+ {0.019430, 0.}
+ };
+ proj_parm.n = 2;
+ par.lam0 = DEG_TO_RAD * 20.;
+ par.phi0 = DEG_TO_RAD * 18.;
+ proj_parm.zcoeff = AB;
+ par.es = 0.;
+ setup(par, proj_parm);
+ }
+
+ // Lee Oblated Stereographic
+ template <typename Parameters>
+ void setup_lee_os(Parameters& par, par_mod_ster& proj_parm)
+ {
+ static COMPLEX /* Lee Oblated Stereographic */
+ AB[] = {
+ {0.721316, 0.},
+ {0., 0.},
+ {-0.0088162, -0.00617325}
+ };
+ proj_parm.n = 2;
+ par.lam0 = DEG_TO_RAD * -165.;
+ par.phi0 = DEG_TO_RAD * -10.;
+ proj_parm.zcoeff = AB;
+ par.es = 0.;
+ setup(par, proj_parm);
+ }
+
+ // Mod. Stererographics of 48 U.S.
+ template <typename Parameters>
+ void setup_gs48(Parameters& par, par_mod_ster& proj_parm)
+ {
+ static COMPLEX /* 48 United States */
+ AB[] = {
+ {0.98879, 0.},
+ {0., 0.},
+ {-0.050909, 0.},
+ {0., 0.},
+ {0.075528, 0.}
+ };
+ proj_parm.n = 4;
+ par.lam0 = DEG_TO_RAD * -96.;
+ par.phi0 = DEG_TO_RAD * -39.;
+ proj_parm.zcoeff = AB;
+ par.es = 0.;
+ par.a = 6370997.;
+ setup(par, proj_parm);
+ }
+
+ // Mod. Stererographics of Alaska
+ template <typename Parameters>
+ void setup_alsk(Parameters& par, par_mod_ster& proj_parm)
+ {
+ static COMPLEX
+ ABe[] = { /* Alaska ellipsoid */
+ {.9945303, 0.},
+ {.0052083, -.0027404},
+ {.0072721, .0048181},
+ {-.0151089, -.1932526},
+ {.0642675, -.1381226},
+ {.3582802, -.2884586}},
+ ABs[] = { /* Alaska sphere */
+ {.9972523, 0.},
+ {.0052513, -.0041175},
+ {.0074606, .0048125},
+ {-.0153783, -.1968253},
+ {.0636871, -.1408027},
+ {.3660976, -.2937382}
+ };
+ proj_parm.n = 5;
+ par.lam0 = DEG_TO_RAD * -152.;
+ par.phi0 = DEG_TO_RAD * 64.;
+ if (par.es) { /* fixed ellipsoid/sphere */
+ proj_parm.zcoeff = ABe;
+ par.a = 6378206.4;
+ par.e = sqrt(par.es = 0.00676866);
+ } else {
+ proj_parm.zcoeff = ABs;
+ par.a = 6370997.;
+ }
+ setup(par, proj_parm);
+ }
+
+ // Mod. Stererographics of 50 U.S.
+ template <typename Parameters>
+ void setup_gs50(Parameters& par, par_mod_ster& proj_parm)
+ {
+ static COMPLEX
+ ABe[] = { /* GS50 ellipsoid */
+ {.9827497, 0.},
+ {.0210669, .0053804},
+ {-.1031415, -.0571664},
+ {-.0323337, -.0322847},
+ {.0502303, .1211983},
+ {.0251805, .0895678},
+ {-.0012315, -.1416121},
+ {.0072202, -.1317091},
+ {-.0194029, .0759677},
+ {-.0210072, .0834037}
+ },
+ ABs[] = { /* GS50 sphere */
+ {.9842990, 0.},
+ {.0211642, .0037608},
+ {-.1036018, -.0575102},
+ {-.0329095, -.0320119},
+ {.0499471, .1223335},
+ {.0260460, .0899805},
+ {.0007388, -.1435792},
+ {.0075848, -.1334108},
+ {-.0216473, .0776645},
+ {-.0225161, .0853673}
+ };
+ proj_parm.n = 9;
+ par.lam0 = DEG_TO_RAD * -120.;
+ par.phi0 = DEG_TO_RAD * 45.;
+ if (par.es) { /* fixed ellipsoid/sphere */
+ proj_parm.zcoeff = ABe;
+ par.a = 6378206.4;
+ par.e = sqrt(par.es = 0.00676866);
+ } else {
+ proj_parm.zcoeff = ABs;
+ par.a = 6370997.;
+ }
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::mod_ster
+ #endif // doxygen
+
+ /*!
+ \brief Miller Oblated Stereographic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azi(mod)
+ \par Example
+ \image html ex_mil_os.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct mil_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline mil_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mod_ster::setup_mil_os(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Lee Oblated Stereographic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azi(mod)
+ \par Example
+ \image html ex_lee_os.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct lee_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline lee_os_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mod_ster::setup_lee_os(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Mod. Stererographics of 48 U.S. projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azi(mod)
+ \par Example
+ \image html ex_gs48.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct gs48_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline gs48_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mod_ster::setup_gs48(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Mod. Stererographics of Alaska projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azi(mod)
+ \par Example
+ \image html ex_alsk.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct alsk_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline alsk_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mod_ster::setup_alsk(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Mod. Stererographics of 50 U.S. projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azi(mod)
+ \par Example
+ \image html ex_gs50.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct gs50_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline gs50_ellipsoid(const Parameters& par) : detail::mod_ster::base_mod_ster_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::mod_ster::setup_gs50(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class mil_os_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<mil_os_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class lee_os_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<lee_os_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class gs48_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gs48_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class alsk_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<alsk_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class gs50_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<gs50_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void mod_ster_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("mil_os", new mil_os_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("lee_os", new lee_os_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("gs48", new gs48_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("alsk", new alsk_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("gs50", new gs50_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MOD_STER_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/moll.hpp b/src/boost/geometry/extensions/gis/projections/proj/moll.hpp
new file mode 100644
index 0000000..df5bf47
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/moll.hpp
@@ -0,0 +1,262 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace moll{
+ static const int MAX_ITER = 10;
+ static const double LOOP_TOL = 1e-7;
+
+ struct par_moll
+ {
+ double C_x, C_y, C_p;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_moll_spheroid : public base_t_fi<base_moll_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_moll m_proj_parm;
+
+ inline base_moll_spheroid(const Parameters& par)
+ : base_t_fi<base_moll_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double k, V;
+ int i;
+
+ k = this->m_proj_parm.C_p * sin(lp_lat);
+ for (i = MAX_ITER; i ; --i) {
+ lp_lat -= V = (lp_lat + sin(lp_lat) - k) /
+ (1. + cos(lp_lat));
+ if (fabs(V) < LOOP_TOL)
+ break;
+ }
+ if (!i)
+ lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI;
+ else
+ lp_lat *= 0.5;
+ xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat);
+ xy_y = this->m_proj_parm.C_y * sin(lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+
+
+ lp_lat = aasin(xy_y / this->m_proj_parm.C_y);
+ lp_lon = xy_x / (this->m_proj_parm.C_x * cos(lp_lat));
+ lp_lat += lp_lat;
+ lp_lat = aasin((lp_lat + sin(lp_lat)) / this->m_proj_parm.C_p);
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_moll& proj_parm, double p)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ double r, sp, p2 = p + p;
+ par.es = 0;
+ sp = sin(p);
+ r = sqrt(TWOPI * sp / (p2 + sin(p2)));
+ proj_parm.C_x = 2. * r / PI;
+ proj_parm.C_y = r / sp;
+ proj_parm.C_p = p2 + sin(p2);
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+
+ // Mollweide
+ template <typename Parameters>
+ void setup_moll(Parameters& par, par_moll& proj_parm)
+ {
+ setup(par, proj_parm, HALFPI);
+ }
+
+ // Wagner IV
+ template <typename Parameters>
+ void setup_wag4(Parameters& par, par_moll& proj_parm)
+ {
+ setup(par, proj_parm, PI/3.);
+ }
+
+ // Wagner V
+ template <typename Parameters>
+ void setup_wag5(Parameters& par, par_moll& proj_parm)
+ {
+ par.es = 0;
+ proj_parm.C_x = 0.90977;
+ proj_parm.C_y = 1.65014;
+ proj_parm.C_p = 3.00896;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::moll
+ #endif // doxygen
+
+ /*!
+ \brief Mollweide projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_moll.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct moll_spheroid : public detail::moll::base_moll_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline moll_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::moll::setup_moll(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Wagner IV projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_wag4.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wag4_spheroid : public detail::moll::base_moll_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wag4_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::moll::setup_wag4(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Wagner V projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_wag5.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wag5_spheroid : public detail::moll::base_moll_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wag5_spheroid(const Parameters& par) : detail::moll::base_moll_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::moll::setup_wag5(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class moll_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<moll_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wag4_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wag4_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wag5_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wag5_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void moll_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("moll", new moll_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("wag4", new wag4_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("wag5", new wag5_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_MOLL_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/nell.hpp b/src/boost/geometry/extensions/gis/projections/proj/nell.hpp
new file mode 100644
index 0000000..2cee423
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/nell.hpp
@@ -0,0 +1,154 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_NELL_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_NELL_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace nell{
+ static const int MAX_ITER = 10;
+ static const double LOOP_TOL = 1e-7;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_nell_spheroid : public base_t_fi<base_nell_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_nell_spheroid(const Parameters& par)
+ : base_t_fi<base_nell_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double k, V;
+ int i;
+
+ k = 2. * sin(lp_lat);
+ V = lp_lat * lp_lat;
+ lp_lat *= 1.00371 + V * (-0.0935382 + V * -0.011412);
+ for (i = MAX_ITER; i ; --i) {
+ lp_lat -= V = (lp_lat + sin(lp_lat) - k) /
+ (1. + cos(lp_lat));
+ if (fabs(V) < LOOP_TOL)
+ break;
+ }
+ xy_x = 0.5 * lp_lon * (1. + cos(lp_lat));
+ xy_y = lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+
+
+ lp_lon = 2. * xy_x / (1. + cos(xy_y));
+ lp_lat = aasin(0.5 * (xy_y + sin(xy_y)));
+ }
+ };
+
+ // Nell
+ template <typename Parameters>
+ void setup_nell(Parameters& par)
+ {
+ par.es = 0;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::nell
+ #endif // doxygen
+
+ /*!
+ \brief Nell projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_nell.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct nell_spheroid : public detail::nell::base_nell_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline nell_spheroid(const Parameters& par) : detail::nell::base_nell_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::nell::setup_nell(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class nell_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<nell_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void nell_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("nell", new nell_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NELL_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/nell_h.hpp b/src/boost/geometry/extensions/gis/projections/proj/nell_h.hpp
new file mode 100644
index 0000000..456c8f3
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/nell_h.hpp
@@ -0,0 +1,153 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace nell_h{
+ static const int NITER = 9;
+ static const double EPS = 1e-7;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_nell_h_spheroid : public base_t_fi<base_nell_h_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_nell_h_spheroid(const Parameters& par)
+ : base_t_fi<base_nell_h_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = 0.5 * lp_lon * (1. + cos(lp_lat));
+ xy_y = 2.0 * (lp_lat - tan(0.5 *lp_lat));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double V, c, p;
+ int i;
+
+ p = 0.5 * xy_y;
+ for (i = NITER; i ; --i) {
+ c = cos(0.5 * lp_lat);
+ lp_lat -= V = (lp_lat - tan(lp_lat/2) - p)/(1. - 0.5/(c*c));
+ if (fabs(V) < EPS)
+ break;
+ }
+ if (!i) {
+ lp_lat = p < 0. ? -HALFPI : HALFPI;
+ lp_lon = 2. * xy_x;
+ } else
+ lp_lon = 2. * xy_x / (1. + cos(lp_lat));
+ }
+ };
+
+ // Nell-Hammer
+ template <typename Parameters>
+ void setup_nell_h(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::nell_h
+ #endif // doxygen
+
+ /*!
+ \brief Nell-Hammer projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_nell_h.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct nell_h_spheroid : public detail::nell_h::base_nell_h_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline nell_h_spheroid(const Parameters& par) : detail::nell_h::base_nell_h_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::nell_h::setup_nell_h(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class nell_h_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<nell_h_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void nell_h_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("nell_h", new nell_h_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NELL_H_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/nocol.hpp b/src/boost/geometry/extensions/gis/projections/proj/nocol.hpp
new file mode 100644
index 0000000..e8e5a1e
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/nocol.hpp
@@ -0,0 +1,160 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace nocol{
+ static const double EPS = 1e-10;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_nocol_spheroid : public base_t_f<base_nocol_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_nocol_spheroid(const Parameters& par)
+ : base_t_f<base_nocol_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ if (fabs(lp_lon) < EPS) {
+ xy_x = 0;
+ xy_y = lp_lat;
+ } else if (fabs(lp_lat) < EPS) {
+ xy_x = lp_lon;
+ xy_y = 0.;
+ } else if (fabs(fabs(lp_lon) - HALFPI) < EPS) {
+ xy_x = lp_lon * cos(lp_lat);
+ xy_y = HALFPI * sin(lp_lat);
+ } else if (fabs(fabs(lp_lat) - HALFPI) < EPS) {
+ xy_x = 0;
+ xy_y = lp_lat;
+ } else {
+ double tb, c, d, m, n, r2, sp;
+
+ tb = HALFPI / lp_lon - lp_lon / HALFPI;
+ c = lp_lat / HALFPI;
+ d = (1 - c * c)/((sp = sin(lp_lat)) - c);
+ r2 = tb / d;
+ r2 *= r2;
+ m = (tb * sp / d - 0.5 * tb)/(1. + r2);
+ n = (sp / r2 + 0.5 * d)/(1. + 1./r2);
+ xy_x = cos(lp_lat);
+ xy_x = sqrt(m * m + xy_x * xy_x / (1. + r2));
+ xy_x = HALFPI * ( m + (lp_lon < 0. ? -xy_x : xy_x));
+ xy_y = sqrt(n * n - (sp * sp / r2 + d * sp - 1.) /
+ (1. + 1./r2));
+ xy_y = HALFPI * ( n + (lp_lat < 0. ? xy_y : -xy_y ));
+ }
+ }
+ };
+
+ // Nicolosi Globular
+ template <typename Parameters>
+ void setup_nicol(Parameters& par)
+ {
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::nocol
+ #endif // doxygen
+
+ /*!
+ \brief Nicolosi Globular projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_nicol.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct nicol_spheroid : public detail::nocol::base_nocol_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline nicol_spheroid(const Parameters& par) : detail::nocol::base_nocol_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::nocol::setup_nicol(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class nicol_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<nicol_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void nocol_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("nicol", new nicol_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NOCOL_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/nsper.hpp b/src/boost/geometry/extensions/gis/projections/proj/nsper.hpp
new file mode 100644
index 0000000..e9e46b9
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/nsper.hpp
@@ -0,0 +1,317 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace nsper{
+ static const double EPS10 = 1.e-10;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ struct par_nsper
+ {
+ double height;
+ double sinph0;
+ double cosph0;
+ double p;
+ double rp;
+ double pn1;
+ double pfact;
+ double h;
+ double cg;
+ double sg;
+ double sw;
+ double cw;
+ int mode;
+ int tilt;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_nsper_spheroid : public base_t_fi<base_nsper_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_nsper m_proj_parm;
+
+ inline base_nsper_spheroid(const Parameters& par)
+ : base_t_fi<base_nsper_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, cosphi, sinphi;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ xy_y = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosphi * coslam;
+ break;
+ case EQUIT:
+ xy_y = cosphi * coslam;
+ break;
+ case S_POLE:
+ xy_y = - sinphi;
+ break;
+ case N_POLE:
+ xy_y = sinphi;
+ break;
+ }
+ if (xy_y < this->m_proj_parm.rp) throw proj_exception();;
+ xy_y = this->m_proj_parm.pn1 / (this->m_proj_parm.p - xy_y);
+ xy_x = xy_y * cosphi * sin(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ xy_y *= (this->m_proj_parm.cosph0 * sinphi -
+ this->m_proj_parm.sinph0 * cosphi * coslam);
+ break;
+ case EQUIT:
+ xy_y *= sinphi;
+ break;
+ case N_POLE:
+ coslam = - coslam;
+ case S_POLE:
+ xy_y *= cosphi * coslam;
+ break;
+ }
+ if (this->m_proj_parm.tilt) {
+ double yt, ba;
+
+ yt = xy_y * this->m_proj_parm.cg + xy_x * this->m_proj_parm.sg;
+ ba = 1. / (yt * this->m_proj_parm.sw * this->m_proj_parm.h + this->m_proj_parm.cw);
+ xy_x = (xy_x * this->m_proj_parm.cg - xy_y * this->m_proj_parm.sg) * this->m_proj_parm.cw * ba;
+ xy_y = yt * ba;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rh, cosz, sinz;
+
+ if (this->m_proj_parm.tilt) {
+ double bm, bq, yt;
+
+ yt = 1./(this->m_proj_parm.pn1 - xy_y * this->m_proj_parm.sw);
+ bm = this->m_proj_parm.pn1 * xy_x * yt;
+ bq = this->m_proj_parm.pn1 * xy_y * this->m_proj_parm.cw * yt;
+ xy_x = bm * this->m_proj_parm.cg + bq * this->m_proj_parm.sg;
+ xy_y = bq * this->m_proj_parm.cg - bm * this->m_proj_parm.sg;
+ }
+ rh = boost::math::hypot(xy_x, xy_y);
+ if ((sinz = 1. - rh * rh * this->m_proj_parm.pfact) < 0.) throw proj_exception();;
+ sinz = (this->m_proj_parm.p - sqrt(sinz)) / (this->m_proj_parm.pn1 / rh + rh / this->m_proj_parm.pn1);
+ cosz = sqrt(1. - sinz * sinz);
+ if (fabs(rh) <= EPS10) {
+ lp_lon = 0.;
+ lp_lat = this->m_par.phi0;
+ } else {
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ lp_lat = asin(cosz * this->m_proj_parm.sinph0 + xy_y * sinz * this->m_proj_parm.cosph0 / rh);
+ xy_y = (cosz - this->m_proj_parm.sinph0 * sin(lp_lat)) * rh;
+ xy_x *= sinz * this->m_proj_parm.cosph0;
+ break;
+ case EQUIT:
+ lp_lat = asin(xy_y * sinz / rh);
+ xy_y = cosz * rh;
+ xy_x *= sinz;
+ break;
+ case N_POLE:
+ lp_lat = asin(cosz);
+ xy_y = -xy_y;
+ break;
+ case S_POLE:
+ lp_lat = - asin(cosz);
+ break;
+ }
+ lp_lon = atan2(xy_x, xy_y);
+ }
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_nsper& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ if ((proj_parm.height = pj_param(par.params, "dh").f) <= 0.) throw proj_exception(-30);
+ if (fabs(fabs(par.phi0) - HALFPI) < EPS10)
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ else if (fabs(par.phi0) < EPS10)
+ proj_parm.mode = EQUIT;
+ else {
+ proj_parm.mode = OBLIQ;
+ proj_parm.sinph0 = sin(par.phi0);
+ proj_parm.cosph0 = cos(par.phi0);
+ }
+ proj_parm.pn1 = proj_parm.height / par.a;
+ /* normalize by radius */
+ proj_parm.p = 1. + proj_parm.pn1;
+ proj_parm.rp = 1. / proj_parm.p;
+ proj_parm.h = 1. / proj_parm.pn1;
+ proj_parm.pfact = (proj_parm.p + 1.) * proj_parm.h;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+
+ // Near-sided perspective
+ template <typename Parameters>
+ void setup_nsper(Parameters& par, par_nsper& proj_parm)
+ {
+ proj_parm.tilt = 0;
+ setup(par, proj_parm);
+ }
+
+ // Tilted perspective
+ template <typename Parameters>
+ void setup_tpers(Parameters& par, par_nsper& proj_parm)
+ {
+ double omega, gamma;
+ omega = pj_param(par.params, "dtilt").f * DEG_TO_RAD;
+ gamma = pj_param(par.params, "dazi").f * DEG_TO_RAD;
+ proj_parm.tilt = 1;
+ proj_parm.cg = cos(gamma);
+ proj_parm.sg = sin(gamma);
+ proj_parm.cw = cos(omega);
+ proj_parm.sw = sin(omega);
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::nsper
+ #endif // doxygen
+
+ /*!
+ \brief Near-sided perspective projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - h=
+ \par Example
+ \image html ex_nsper.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct nsper_spheroid : public detail::nsper::base_nsper_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline nsper_spheroid(const Parameters& par) : detail::nsper::base_nsper_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::nsper::setup_nsper(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Tilted perspective projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - tilt= azi= h=
+ \par Example
+ \image html ex_tpers.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct tpers_spheroid : public detail::nsper::base_nsper_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline tpers_spheroid(const Parameters& par) : detail::nsper::base_nsper_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::nsper::setup_tpers(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class nsper_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<nsper_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class tpers_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<tpers_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void nsper_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("nsper", new nsper_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("tpers", new tpers_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NSPER_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/nzmg.hpp b/src/boost/geometry/extensions/gis/projections/proj/nzmg.hpp
new file mode 100644
index 0000000..e0a9589
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/nzmg.hpp
@@ -0,0 +1,196 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace nzmg{
+ static const double EPSLN = 1e-10;
+ static const double SEC5_TO_RAD = 0.4848136811095359935899141023;
+ static const double RAD_TO_SEC5 = 2.062648062470963551564733573;
+ static const int Nbf = 5;
+ static const int Ntpsi = 9;
+ static const int Ntphi = 8;
+
+
+
+
+
+ static COMPLEX
+ bf[] = {
+ {.7557853228, 0.0},
+ {.249204646, .003371507},
+ {-.001541739, .041058560},
+ {-.10162907, .01727609},
+ {-.26623489, -.36249218},
+ {-.6870983, -1.1651967} };
+ static double
+ tphi[] = { 1.5627014243, .5185406398, -.03333098, -.1052906, -.0368594,
+ .007317, .01220, .00394, -.0013 },
+ tpsi[] = { .6399175073, -.1358797613, .063294409, -.02526853, .0117879,
+ -.0055161, .0026906, -.001333, .00067, -.00034 };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_nzmg_ellipsoid : public base_t_fi<base_nzmg_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_nzmg_ellipsoid(const Parameters& par)
+ : base_t_fi<base_nzmg_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ COMPLEX p;
+ double *C;
+ int i;
+
+ lp_lat = (lp_lat - this->m_par.phi0) * RAD_TO_SEC5;
+ for (p.r = *(C = tpsi + (i = Ntpsi)); i ; --i)
+ p.r = *--C + lp_lat * p.r;
+ p.r *= lp_lat;
+ p.i = lp_lon;
+ p = pj_zpoly1(p, bf, Nbf);
+ xy_x = p.i;
+ xy_y = p.r;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ int nn, i;
+ COMPLEX p, f, fp, dp;
+ double den, *C;
+
+ p.r = xy_y;
+ p.i = xy_x;
+ for (nn = 20; nn ;--nn) {
+ f = pj_zpolyd1(p, bf, Nbf, &fp);
+ f.r -= xy_y;
+ f.i -= xy_x;
+ den = fp.r * fp.r + fp.i * fp.i;
+ p.r += dp.r = -(f.r * fp.r + f.i * fp.i) / den;
+ p.i += dp.i = -(f.i * fp.r - f.r * fp.i) / den;
+ if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN)
+ break;
+ }
+ if (nn) {
+ lp_lon = p.i;
+ for (lp_lat = *(C = tphi + (i = Ntphi)); i ; --i)
+ lp_lat = *--C + p.r * lp_lat;
+ lp_lat = this->m_par.phi0 + p.r * lp_lat * SEC5_TO_RAD;
+ } else
+ lp_lon = lp_lat = HUGE_VAL;
+ }
+ };
+
+ // New Zealand Map Grid
+ template <typename Parameters>
+ void setup_nzmg(Parameters& par)
+ {
+ /* force to International major axis */
+ par.ra = 1. / (par.a = 6378388.0);
+ par.lam0 = DEG_TO_RAD * 173.;
+ par.phi0 = DEG_TO_RAD * -41.;
+ par.x0 = 2510000.;
+ par.y0 = 6023150.;
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+ }} // namespace detail::nzmg
+ #endif // doxygen
+
+ /*!
+ \brief New Zealand Map Grid projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - fixed Earth
+ \par Example
+ \image html ex_nzmg.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct nzmg_ellipsoid : public detail::nzmg::base_nzmg_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline nzmg_ellipsoid(const Parameters& par) : detail::nzmg::base_nzmg_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::nzmg::setup_nzmg(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class nzmg_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<nzmg_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void nzmg_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("nzmg", new nzmg_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_NZMG_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/ob_tran.hpp b/src/boost/geometry/extensions/gis/projections/proj/ob_tran.hpp
new file mode 100644
index 0000000..6e2f313
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/ob_tran.hpp
@@ -0,0 +1,318 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/shared_ptr.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+ template <typename Geographic, typename Cartesian, typename Parameters> class factory;
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace ob_tran{
+ static const double TOL = 1e-10;
+
+ template <typename Geographic, typename Cartesian>
+ struct par_ob_tran
+ {
+ boost::shared_ptr<projection<Geographic, Cartesian> > link;
+ double lamp;
+ double cphip, sphip;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_ob_tran_oblique : public base_t_fi<base_ob_tran_oblique<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_ob_tran<Geographic, Cartesian> m_proj_parm;
+
+ inline base_ob_tran_oblique(const Parameters& par)
+ : base_t_fi<base_ob_tran_oblique<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, sinphi, cosphi;
+
+
+
+ coslam = cos(lp_lon);
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), this->m_proj_parm.sphip * cosphi * coslam +
+ this->m_proj_parm.cphip * sinphi) + this->m_proj_parm.lamp);
+ lp_lat = aasin(this->m_proj_parm.sphip * sinphi - this->m_proj_parm.cphip * cosphi * coslam);
+ m_proj_parm.link->fwd(lp_lon, lp_lat, xy_x, xy_y);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double coslam, sinphi, cosphi;
+
+ m_proj_parm.link->inv(xy_x, xy_y, lp_lon, lp_lat);
+ if (lp_lon != HUGE_VAL) {
+ coslam = cos(lp_lon -= this->m_proj_parm.lamp);
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ lp_lat = aasin(this->m_proj_parm.sphip * sinphi + this->m_proj_parm.cphip * cosphi * coslam);
+ lp_lon = aatan2(cosphi * sin(lp_lon), this->m_proj_parm.sphip * cosphi * coslam -
+ this->m_proj_parm.cphip * sinphi);
+ }
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_ob_tran_transverse : public base_t_fi<base_ob_tran_transverse<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_ob_tran<Geographic, Cartesian> m_proj_parm;
+
+ inline base_ob_tran_transverse(const Parameters& par)
+ : base_t_fi<base_ob_tran_transverse<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double cosphi, coslam;
+
+
+
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), sin(lp_lat)) + this->m_proj_parm.lamp);
+ lp_lat = aasin(- cosphi * coslam);
+ m_proj_parm.link->fwd(lp_lon, lp_lat, xy_x, xy_y);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double cosphi, t;
+
+ m_proj_parm.link->inv(xy_x, xy_y, lp_lon, lp_lat);
+ if (lp_lon != HUGE_VAL) {
+ cosphi = cos(lp_lat);
+ t = lp_lon - this->m_proj_parm.lamp;
+ lp_lon = aatan2(cosphi * sin(t), - sin(lp_lat));
+ lp_lat = aasin(cosphi * cos(t));
+ }
+ }
+ };
+
+ // General Oblique Transformation
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ double setup_ob_tran(Parameters& par, par_ob_tran<Geographic, Cartesian>& proj_parm, bool create = true)
+ {
+ int i;
+ double phip;
+
+
+ Parameters pj;
+ /* copy existing header into new */
+ par.es = 0.;
+ /* force to spherical */
+ pj.params = par.params;
+ pj.over = par.over;
+ pj.geoc = par.geoc;
+ pj.a = par.a;
+ pj.es = par.es;
+ pj.ra = par.ra;
+ pj.lam0 = par.lam0;
+ pj.phi0 = par.phi0;
+ pj.x0 = par.x0;
+ pj.y0 = par.y0;
+ pj.k0 = par.k0;
+ /* force spherical earth */
+ pj.one_es = pj.rone_es = 1.;
+ pj.es = pj.e = 0.;
+ pj.name = pj_param(par.params, "so_proj").s;
+
+ factory<Geographic, Cartesian, Parameters> fac;
+ if (create)
+ {
+ proj_parm.link.reset(fac.create_new(pj));
+ if (! proj_parm.link.get()) throw proj_exception(-26);
+ }
+ if (pj_param(par.params, "to_alpha").i) {
+ double lamc, phic, alpha;
+ lamc = pj_param(par.params, "ro_lon_c").f;
+ phic = pj_param(par.params, "ro_lat_c").f;
+ alpha = pj_param(par.params, "ro_alpha").f;
+ /*
+ if (fabs(phic) <= TOL ||
+ fabs(fabs(phic) - HALFPI) <= TOL ||
+ fabs(fabs(alpha) - HALFPI) <= TOL)
+ */
+ if (fabs(fabs(phic) - HALFPI) <= TOL)
+ throw proj_exception(-32);
+ proj_parm.lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic));
+ phip = aasin(cos(phic) * sin(alpha));
+ } else if (pj_param(par.params, "to_lat_p").i) { /* specified new pole */
+ proj_parm.lamp = pj_param(par.params, "ro_lon_p").f;
+ phip = pj_param(par.params, "ro_lat_p").f;
+ } else { /* specified new "equator" points */
+ double lam1, lam2, phi1, phi2, con;
+ lam1 = pj_param(par.params, "ro_lon_1").f;
+ phi1 = pj_param(par.params, "ro_lat_1").f;
+ lam2 = pj_param(par.params, "ro_lon_2").f;
+ phi2 = pj_param(par.params, "ro_lat_2").f;
+ if (fabs(phi1 - phi2) <= TOL ||
+ (con = fabs(phi1)) <= TOL ||
+ fabs(con - HALFPI) <= TOL ||
+ fabs(fabs(phi2) - HALFPI) <= TOL) throw proj_exception(-33);
+ proj_parm.lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) -
+ sin(phi1) * cos(phi2) * cos(lam2),
+ sin(phi1) * cos(phi2) * sin(lam2) -
+ cos(phi1) * sin(phi2) * sin(lam1));
+ phip = atan(-cos(proj_parm.lamp - lam1) / tan(phi1));
+ }
+ if (fabs(phip) > TOL) { /* oblique */
+ proj_parm.cphip = cos(phip);
+ proj_parm.sphip = sin(phip);
+ // par.fwd = o_forward;
+ // par.inv = pj.inv ? o_inverse : 0;
+ } else { /* transverse */
+ // par.fwd = t_forward;
+ // par.inv = pj.inv ? t_inverse : 0;
+ }
+ boost::ignore_unused_variable_warning(i);
+ // return phip to choose model
+ return phip;
+ }
+
+ }} // namespace detail::ob_tran
+ #endif // doxygen
+
+ /*!
+ \brief General Oblique Transformation projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - o_proj= plus parameters for projection
+ - o_lat_p= o_lon_p= (new pole) or
+ - o_alpha= o_lon_c= o_lat_c= or
+ - o_lon_1= o_lat_1= o_lon_2= o_lat_2=
+ \par Example
+ \image html ex_ob_tran.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique<Geographic, Cartesian, Parameters>
+ {
+ inline ob_tran_oblique(const Parameters& par) : detail::ob_tran::base_ob_tran_oblique<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief General Oblique Transformation projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - o_proj= plus parameters for projection
+ - o_lat_p= o_lon_p= (new pole) or
+ - o_alpha= o_lon_c= o_lat_c= or
+ - o_lon_1= o_lat_1= o_lon_2= o_lat_2=
+ \par Example
+ \image html ex_ob_tran.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse<Geographic, Cartesian, Parameters>
+ {
+ inline ob_tran_transverse(const Parameters& par) : detail::ob_tran::base_ob_tran_transverse<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class ob_tran_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ detail::ob_tran::par_ob_tran<Geographic, Cartesian> proj_parm;
+ Parameters p = par;
+ double phip = setup_ob_tran(p, proj_parm, false);
+ if (fabs(phip) > detail::ob_tran::TOL)
+ return new base_v_fi<ob_tran_oblique<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<ob_tran_transverse<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void ob_tran_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("ob_tran", new ob_tran_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/ocea.hpp b/src/boost/geometry/extensions/gis/projections/proj/ocea.hpp
new file mode 100644
index 0000000..2cf4d50
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/ocea.hpp
@@ -0,0 +1,189 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace ocea{
+
+ struct par_ocea
+ {
+ double rok;
+ double rtk;
+ double sinphi;
+ double cosphi;
+ double singam;
+ double cosgam;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_ocea_spheroid : public base_t_fi<base_ocea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_ocea m_proj_parm;
+
+ inline base_ocea_spheroid(const Parameters& par)
+ : base_t_fi<base_ocea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double t;
+
+ xy_y = sin(lp_lon);
+ /*
+ xy_x = atan2((tan(lp_lat) * this->m_proj_parm.cosphi + this->m_proj_parm.sinphi * xy_y) , cos(lp_lon));
+ */
+ t = cos(lp_lon);
+ xy_x = atan((tan(lp_lat) * this->m_proj_parm.cosphi + this->m_proj_parm.sinphi * xy_y) / t);
+ if (t < 0.)
+ xy_x += PI;
+ xy_x *= this->m_proj_parm.rtk;
+ xy_y = this->m_proj_parm.rok * (this->m_proj_parm.sinphi * sin(lp_lat) - this->m_proj_parm.cosphi * cos(lp_lat) * xy_y);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double t, s;
+
+ xy_y /= this->m_proj_parm.rok;
+ xy_x /= this->m_proj_parm.rtk;
+ t = sqrt(1. - xy_y * xy_y);
+ lp_lat = asin(xy_y * this->m_proj_parm.sinphi + t * this->m_proj_parm.cosphi * (s = sin(xy_x)));
+ lp_lon = atan2(t * this->m_proj_parm.sinphi * s - xy_y * this->m_proj_parm.cosphi,
+ t * cos(xy_x));
+ }
+ };
+
+ // Oblique Cylindrical Equal Area
+ template <typename Parameters>
+ void setup_ocea(Parameters& par, par_ocea& proj_parm)
+ {
+ double phi_0=0.0, phi_1, phi_2, lam_1, lam_2, lonz, alpha;
+ proj_parm.rok = par.a / par.k0;
+ proj_parm.rtk = par.a * par.k0;
+ if ( pj_param(par.params, "talpha").i) {
+ alpha = pj_param(par.params, "ralpha").f;
+ lonz = pj_param(par.params, "rlonc").f;
+ proj_parm.singam = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz;
+ proj_parm.sinphi = asin(cos(phi_0) * sin(alpha));
+ } else {
+ phi_1 = pj_param(par.params, "rlat_1").f;
+ phi_2 = pj_param(par.params, "rlat_2").f;
+ lam_1 = pj_param(par.params, "rlon_1").f;
+ lam_2 = pj_param(par.params, "rlon_2").f;
+ proj_parm.singam = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) -
+ sin(phi_1) * cos(phi_2) * cos(lam_2),
+ sin(phi_1) * cos(phi_2) * sin(lam_2) -
+ cos(phi_1) * sin(phi_2) * sin(lam_1) );
+ proj_parm.sinphi = atan(-cos(proj_parm.singam - lam_1) / tan(phi_1));
+ }
+ par.lam0 = proj_parm.singam + HALFPI;
+ proj_parm.cosphi = cos(proj_parm.sinphi);
+ proj_parm.sinphi = sin(proj_parm.sinphi);
+ proj_parm.cosgam = cos(proj_parm.singam);
+ proj_parm.singam = sin(proj_parm.singam);
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::ocea
+ #endif // doxygen
+
+ /*!
+ \brief Oblique Cylindrical Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Sph lonc= alpha= or
+ - lat_1= lat_2= lon_1= lon_2=
+ \par Example
+ \image html ex_ocea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct ocea_spheroid : public detail::ocea::base_ocea_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline ocea_spheroid(const Parameters& par) : detail::ocea::base_ocea_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::ocea::setup_ocea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class ocea_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<ocea_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void ocea_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("ocea", new ocea_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_OCEA_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/oea.hpp b/src/boost/geometry/extensions/gis/projections/proj/oea.hpp
new file mode 100644
index 0000000..238bc37
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/oea.hpp
@@ -0,0 +1,181 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_OEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_OEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace oea{
+
+ struct par_oea
+ {
+ double theta;
+ double m, n;
+ double two_r_m, two_r_n, rm, rn, hm, hn;
+ double cp0, sp0;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_oea_spheroid : public base_t_fi<base_oea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_oea m_proj_parm;
+
+ inline base_oea_spheroid(const Parameters& par)
+ : base_t_fi<base_oea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double Az, M, N, cp, sp, cl, shz;
+
+ cp = cos(lp_lat);
+ sp = sin(lp_lat);
+ cl = cos(lp_lon);
+ Az = aatan2(cp * sin(lp_lon), this->m_proj_parm.cp0 * sp - this->m_proj_parm.sp0 * cp * cl) + this->m_proj_parm.theta;
+ shz = sin(0.5 * aacos(this->m_proj_parm.sp0 * sp + this->m_proj_parm.cp0 * cp * cl));
+ M = aasin(shz * sin(Az));
+ N = aasin(shz * cos(Az) * cos(M) / cos(M * this->m_proj_parm.two_r_m));
+ xy_y = this->m_proj_parm.n * sin(N * this->m_proj_parm.two_r_n);
+ xy_x = this->m_proj_parm.m * sin(M * this->m_proj_parm.two_r_m) * cos(N) / cos(N * this->m_proj_parm.two_r_n);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double N, M, xp, yp, z, Az, cz, sz, cAz;
+
+ N = this->m_proj_parm.hn * aasin(xy_y * this->m_proj_parm.rn);
+ M = this->m_proj_parm.hm * aasin(xy_x * this->m_proj_parm.rm * cos(N * this->m_proj_parm.two_r_n) / cos(N));
+ xp = 2. * sin(M);
+ yp = 2. * sin(N) * cos(M * this->m_proj_parm.two_r_m) / cos(M);
+ cAz = cos(Az = aatan2(xp, yp) - this->m_proj_parm.theta);
+ z = 2. * aasin(0.5 * boost::math::hypot(xp, yp));
+ sz = sin(z);
+ cz = cos(z);
+ lp_lat = aasin(this->m_proj_parm.sp0 * cz + this->m_proj_parm.cp0 * sz * cAz);
+ lp_lon = aatan2(sz * sin(Az),
+ this->m_proj_parm.cp0 * cz - this->m_proj_parm.sp0 * sz * cAz);
+ }
+ };
+
+ // Oblated Equal Area
+ template <typename Parameters>
+ void setup_oea(Parameters& par, par_oea& proj_parm)
+ {
+ if (((proj_parm.n = pj_param(par.params, "dn").f) <= 0.) ||
+ ((proj_parm.m = pj_param(par.params, "dm").f) <= 0.))
+ throw proj_exception(-39);
+ else {
+ proj_parm.theta = pj_param(par.params, "rtheta").f;
+ proj_parm.sp0 = sin(par.phi0);
+ proj_parm.cp0 = cos(par.phi0);
+ proj_parm.rn = 1./ proj_parm.n;
+ proj_parm.rm = 1./ proj_parm.m;
+ proj_parm.two_r_n = 2. * proj_parm.rn;
+ proj_parm.two_r_m = 2. * proj_parm.rm;
+ proj_parm.hm = 0.5 * proj_parm.m;
+ proj_parm.hn = 0.5 * proj_parm.n;
+ // par.fwd = s_forward;
+ // par.inv = s_inverse;
+ par.es = 0.;
+ }
+ }
+
+ }} // namespace detail::oea
+ #endif // doxygen
+
+ /*!
+ \brief Oblated Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - n= m= theta=
+ \par Example
+ \image html ex_oea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct oea_spheroid : public detail::oea::base_oea_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline oea_spheroid(const Parameters& par) : detail::oea::base_oea_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::oea::setup_oea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class oea_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<oea_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void oea_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("oea", new oea_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_OEA_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/omerc.hpp b/src/boost/geometry/extensions/gis/projections/proj/omerc.hpp
new file mode 100644
index 0000000..4f578d1
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/omerc.hpp
@@ -0,0 +1,295 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_phi2.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace omerc{
+ static const double TOL = 1.e-7;
+ static const double EPS = 1.e-10;
+
+ inline double TSFN0(double x)
+ {return tan(.5 * (HALFPI - (x))); }
+
+
+ struct par_omerc
+ {
+ double A, B, E, AB, ArB, BrA, rB, singam, cosgam, sinrot, cosrot;
+ double v_pole_n, v_pole_s, u_0;
+ int no_rot;
+ };
+
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_omerc_ellipsoid : public base_t_fi<base_omerc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_omerc m_proj_parm;
+
+ inline base_omerc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_omerc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double Q, S, T, U, V, temp, u, v;
+
+ if (fabs(fabs(lp_lat) - HALFPI) > EPS) {
+ Q = this->m_proj_parm.E / pow(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e), this->m_proj_parm.B);
+ temp = 1. / Q;
+ S = .5 * (Q - temp);
+ T = .5 * (Q + temp);
+ V = sin(this->m_proj_parm.B * lp_lon);
+ U = (S * this->m_proj_parm.singam - V * this->m_proj_parm.cosgam) / T;
+ if (fabs(fabs(U) - 1.0) < EPS)
+ throw proj_exception();;
+ v = 0.5 * this->m_proj_parm.ArB * log((1. - U)/(1. + U));
+ temp = cos(this->m_proj_parm.B * lp_lon);
+ u = (fabs(temp) < TOL) ? this->m_proj_parm.AB * lp_lon :
+ this->m_proj_parm.ArB * atan2((S * this->m_proj_parm.cosgam + V * this->m_proj_parm.singam) , temp);
+ } else {
+ v = lp_lat > 0 ? this->m_proj_parm.v_pole_n : this->m_proj_parm.v_pole_s;
+ u = this->m_proj_parm.ArB * lp_lat;
+ }
+ if (this->m_proj_parm.no_rot) {
+ xy_x = u;
+ xy_y = v;
+ } else {
+ u -= this->m_proj_parm.u_0;
+ xy_x = v * this->m_proj_parm.cosrot + u * this->m_proj_parm.sinrot;
+ xy_y = u * this->m_proj_parm.cosrot - v * this->m_proj_parm.sinrot;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double u, v, Qp, Sp, Tp, Vp, Up;
+
+ if (this->m_proj_parm.no_rot) {
+ v = xy_y;
+ u = xy_x;
+ } else {
+ v = xy_x * this->m_proj_parm.cosrot - xy_y * this->m_proj_parm.sinrot;
+ u = xy_y * this->m_proj_parm.cosrot + xy_x * this->m_proj_parm.sinrot + this->m_proj_parm.u_0;
+ }
+ Qp = exp(- this->m_proj_parm.BrA * v);
+ Sp = .5 * (Qp - 1. / Qp);
+ Tp = .5 * (Qp + 1. / Qp);
+ Vp = sin(this->m_proj_parm.BrA * u);
+ Up = (Vp * this->m_proj_parm.cosgam + Sp * this->m_proj_parm.singam) / Tp;
+ if (fabs(fabs(Up) - 1.) < EPS) {
+ lp_lon = 0.;
+ lp_lat = Up < 0. ? -HALFPI : HALFPI;
+ } else {
+ lp_lat = this->m_proj_parm.E / sqrt((1. + Up) / (1. - Up));
+ if ((lp_lat = pj_phi2(pow(lp_lat, 1. / this->m_proj_parm.B), this->m_par.e)) == HUGE_VAL)
+ throw proj_exception();;
+ lp_lon = - this->m_proj_parm.rB * atan2((Sp * this->m_proj_parm.cosgam -
+ Vp * this->m_proj_parm.singam), cos(this->m_proj_parm.BrA * u));
+ }
+ }
+ };
+
+ // Oblique Mercator
+ template <typename Parameters>
+ void setup_omerc(Parameters& par, par_omerc& proj_parm)
+ {
+ double con, com, cosph0, D, F, H, L, sinph0, p, J, gamma,
+ gamma0, lamc, lam1, lam2, phi1, phi2, alpha_c;
+ int alp, gam, no_off = 0;
+ proj_parm.no_rot = pj_param(par.params, "tno_rot").i;
+ if ((alp = pj_param(par.params, "talpha").i))
+ alpha_c = pj_param(par.params, "ralpha").f;
+ if ((gam = pj_param(par.params, "tgamma").i))
+ gamma = pj_param(par.params, "rgamma").f;
+ if (alp || gam) {
+ lamc = pj_param(par.params, "rlonc").f;
+ no_off = pj_param(par.params, "tno_off").i;
+ } else {
+ lam1 = pj_param(par.params, "rlon_1").f;
+ phi1 = pj_param(par.params, "rlat_1").f;
+ lam2 = pj_param(par.params, "rlon_2").f;
+ phi2 = pj_param(par.params, "rlat_2").f;
+ if (fabs(phi1 - phi2) <= TOL ||
+ (con = fabs(phi1)) <= TOL ||
+ fabs(con - HALFPI) <= TOL ||
+ fabs(fabs(par.phi0) - HALFPI) <= TOL ||
+ fabs(fabs(phi2) - HALFPI) <= TOL) throw proj_exception(-33);
+ }
+ com = sqrt(par.one_es);
+ if (fabs(par.phi0) > EPS) {
+ sinph0 = sin(par.phi0);
+ cosph0 = cos(par.phi0);
+ con = 1. - par.es * sinph0 * sinph0;
+ proj_parm.B = cosph0 * cosph0;
+ proj_parm.B = sqrt(1. + par.es * proj_parm.B * proj_parm.B / par.one_es);
+ proj_parm.A = proj_parm.B * par.k0 * com / con;
+ D = proj_parm.B * com / (cosph0 * sqrt(con));
+ if ((F = D * D - 1.) <= 0.)
+ F = 0.;
+ else {
+ F = sqrt(F);
+ if (par.phi0 < 0.)
+ F = -F;
+ }
+ proj_parm.E = F += D;
+ proj_parm.E *= pow(pj_tsfn(par.phi0, sinph0, par.e), proj_parm.B);
+ } else {
+ proj_parm.B = 1. / com;
+ proj_parm.A = par.k0;
+ proj_parm.E = D = F = 1.;
+ }
+ if (alp || gam) {
+ if (alp) {
+ gamma0 = asin(sin(alpha_c) / D);
+ if (!gam)
+ gamma = alpha_c;
+ } else
+ alpha_c = asin(D*sin(gamma0 = gamma));
+ if ((con = fabs(alpha_c)) <= TOL ||
+ fabs(con - PI) <= TOL ||
+ fabs(fabs(par.phi0) - HALFPI) <= TOL)
+ throw proj_exception(-32);
+ par.lam0 = lamc - asin(.5 * (F - 1. / F) *
+ tan(gamma0)) / proj_parm.B;
+ } else {
+ H = pow(pj_tsfn(phi1, sin(phi1), par.e), proj_parm.B);
+ L = pow(pj_tsfn(phi2, sin(phi2), par.e), proj_parm.B);
+ F = proj_parm.E / H;
+ p = (L - H) / (L + H);
+ J = proj_parm.E * proj_parm.E;
+ J = (J - L * H) / (J + L * H);
+ if ((con = lam1 - lam2) < -PI)
+ lam2 -= TWOPI;
+ else if (con > PI)
+ lam2 += TWOPI;
+ par.lam0 = adjlon(.5 * (lam1 + lam2) - atan(
+ J * tan(.5 * proj_parm.B * (lam1 - lam2)) / p) / proj_parm.B);
+ gamma0 = atan(2. * sin(proj_parm.B * adjlon(lam1 - par.lam0)) /
+ (F - 1. / F));
+ gamma = alpha_c = asin(D * sin(gamma0));
+ }
+ proj_parm.singam = sin(gamma0);
+ proj_parm.cosgam = cos(gamma0);
+ proj_parm.sinrot = sin(gamma);
+ proj_parm.cosrot = cos(gamma);
+ proj_parm.BrA = 1. / (proj_parm.ArB = proj_parm.A * (proj_parm.rB = 1. / proj_parm.B));
+ proj_parm.AB = proj_parm.A * proj_parm.B;
+ if (no_off)
+ proj_parm.u_0 = 0;
+ else {
+ proj_parm.u_0 = fabs(proj_parm.ArB * atan2(sqrt(D * D - 1.), cos(alpha_c)));
+ if (par.phi0 < 0.)
+ proj_parm.u_0 = - proj_parm.u_0;
+ }
+ F = 0.5 * gamma0;
+ proj_parm.v_pole_n = proj_parm.ArB * log(tan(FORTPI - F));
+ proj_parm.v_pole_s = proj_parm.ArB * log(tan(FORTPI + F));
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+ }} // namespace detail::omerc
+ #endif // doxygen
+
+ /*!
+ \brief Oblique Mercator projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ell no_rot
+ - alpha= [gamma=] [no_off] lonc= or
+ - lon_1= lat_1= lon_2= lat_2=
+ \par Example
+ \image html ex_omerc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct omerc_ellipsoid : public detail::omerc::base_omerc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline omerc_ellipsoid(const Parameters& par) : detail::omerc::base_omerc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::omerc::setup_omerc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class omerc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<omerc_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void omerc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("omerc", new omerc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_OMERC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/ortho.hpp b/src/boost/geometry/extensions/gis/projections/proj/ortho.hpp
new file mode 100644
index 0000000..6064b27
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/ortho.hpp
@@ -0,0 +1,219 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace ortho{
+ static const double EPS10 = 1.e-10;
+ static const int N_POLE = 0;
+ static const int S_POLE = 1;
+ static const int EQUIT = 2;
+ static const int OBLIQ = 3;
+
+ struct par_ortho
+ {
+ double sinph0;
+ double cosph0;
+ int mode;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_ortho_spheroid : public base_t_fi<base_ortho_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_ortho m_proj_parm;
+
+ inline base_ortho_spheroid(const Parameters& par)
+ : base_t_fi<base_ortho_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, cosphi, sinphi;
+
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ if (cosphi * coslam < - EPS10) throw proj_exception();;
+ xy_y = sin(lp_lat);
+ break;
+ case OBLIQ:
+ if (this->m_proj_parm.sinph0 * (sinphi = sin(lp_lat)) +
+ this->m_proj_parm.cosph0 * cosphi * coslam < - EPS10) throw proj_exception();;
+ xy_y = this->m_proj_parm.cosph0 * sinphi - this->m_proj_parm.sinph0 * cosphi * coslam;
+ break;
+ case N_POLE:
+ coslam = - coslam;
+ case S_POLE:
+ if (fabs(lp_lat - this->m_par.phi0) - EPS10 > HALFPI) throw proj_exception();;
+ xy_y = cosphi * coslam;
+ break;
+ }
+ xy_x = cosphi * sin(lp_lon);
+ return;
+ }
+
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rh, cosc, sinc;
+
+ if ((sinc = (rh = boost::math::hypot(xy_x, xy_y))) > 1.) {
+ if ((sinc - 1.) > EPS10) throw proj_exception();;
+ sinc = 1.;
+ }
+ cosc = sqrt(1. - sinc * sinc); /* in this range OK */
+ if (fabs(rh) <= EPS10) {
+ lp_lat = this->m_par.phi0;
+ lp_lon = 0.0;
+ } else {
+ switch (this->m_proj_parm.mode) {
+ case N_POLE:
+ xy_y = -xy_y;
+ lp_lat = acos(sinc);
+ break;
+ case S_POLE:
+ lp_lat = - acos(sinc);
+ break;
+ case EQUIT:
+ lp_lat = xy_y * sinc / rh;
+ xy_x *= sinc;
+ xy_y = cosc * rh;
+ goto sinchk;
+ case OBLIQ:
+ lp_lat = cosc * this->m_proj_parm.sinph0 + xy_y * sinc * this->m_proj_parm.cosph0 /rh;
+ xy_y = (cosc - this->m_proj_parm.sinph0 * lp_lat) * rh;
+ xy_x *= sinc * this->m_proj_parm.cosph0;
+ sinchk:
+ if (fabs(lp_lat) >= 1.)
+ lp_lat = lp_lat < 0. ? -HALFPI : HALFPI;
+ else
+ lp_lat = asin(lp_lat);
+ break;
+ }
+ lp_lon = (xy_y == 0. && (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT))
+ ? (xy_x == 0. ? 0. : xy_x < 0. ? -HALFPI : HALFPI)
+ : atan2(xy_x, xy_y);
+ }
+ return;
+ }
+
+ };
+
+ // Orthographic
+ template <typename Parameters>
+ void setup_ortho(Parameters& par, par_ortho& proj_parm)
+ {
+ if (fabs(fabs(par.phi0) - HALFPI) <= EPS10)
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ else if (fabs(par.phi0) > EPS10) {
+ proj_parm.mode = OBLIQ;
+ proj_parm.sinph0 = sin(par.phi0);
+ proj_parm.cosph0 = cos(par.phi0);
+ } else
+ proj_parm.mode = EQUIT;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::ortho
+ #endif // doxygen
+
+ /*!
+ \brief Orthographic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ \par Example
+ \image html ex_ortho.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct ortho_spheroid : public detail::ortho::base_ortho_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline ortho_spheroid(const Parameters& par) : detail::ortho::base_ortho_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::ortho::setup_ortho(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class ortho_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<ortho_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void ortho_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("ortho", new ortho_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ORTHO_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/poly.hpp b/src/boost/geometry/extensions/gis/projections/proj/poly.hpp
new file mode 100644
index 0000000..917ad6c
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/poly.hpp
@@ -0,0 +1,266 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_POLY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_POLY_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_msfn.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace poly{
+ static const double TOL = 1e-10;
+ static const double CONV = 1e-10;
+ static const int N_ITER = 10;
+ static const int I_ITER = 20;
+ static const double ITOL = 1.e-12;
+
+ struct par_poly
+ {
+ double ml0;
+ double en[EN_SIZE];
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_poly_ellipsoid : public base_t_fi<base_poly_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_poly m_proj_parm;
+
+ inline base_poly_ellipsoid(const Parameters& par)
+ : base_t_fi<base_poly_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double ms, sp, cp;
+
+ if (fabs(lp_lat) <= TOL) { xy_x = lp_lon; xy_y = -this->m_proj_parm.ml0; }
+ else {
+ sp = sin(lp_lat);
+ ms = fabs(cp = cos(lp_lat)) > TOL ? pj_msfn(sp, cp, this->m_par.es) / sp : 0.;
+ xy_x = ms * sin(lp_lon *= sp);
+ xy_y = (pj_mlfn(lp_lat, sp, cp, this->m_proj_parm.en) - this->m_proj_parm.ml0) + ms * (1. - cos(lp_lon));
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ xy_y += this->m_proj_parm.ml0;
+ if (fabs(xy_y) <= TOL) { lp_lon = xy_x; lp_lat = 0.; }
+ else {
+ double r, c, sp, cp, s2ph, ml, mlb, mlp, dPhi;
+ int i;
+
+ r = xy_y * xy_y + xy_x * xy_x;
+ for (lp_lat = xy_y, i = I_ITER; i ; --i) {
+ sp = sin(lp_lat);
+ s2ph = sp * ( cp = cos(lp_lat));
+ if (fabs(cp) < ITOL)
+ throw proj_exception();;
+ c = sp * (mlp = sqrt(1. - this->m_par.es * sp * sp)) / cp;
+ ml = pj_mlfn(lp_lat, sp, cp, this->m_proj_parm.en);
+ mlb = ml * ml + r;
+ mlp = this->m_par.one_es / (mlp * mlp * mlp);
+ lp_lat += ( dPhi =
+ ( ml + ml + c * mlb - 2. * xy_y * (c * ml + 1.) ) / (
+ this->m_par.es * s2ph * (mlb - 2. * xy_y * ml) / c +
+ 2.* (xy_y - ml) * (c * mlp - 1. / s2ph) - mlp - mlp ));
+ if (fabs(dPhi) <= ITOL)
+ break;
+ }
+ if (!i)
+ throw proj_exception();;
+ c = sin(lp_lat);
+ lp_lon = asin(xy_x * tan(lp_lat) * sqrt(1. - this->m_par.es * c * c)) / sin(lp_lat);
+ }
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_poly_spheroid : public base_t_fi<base_poly_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_poly m_proj_parm;
+
+ inline base_poly_spheroid(const Parameters& par)
+ : base_t_fi<base_poly_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double cot, E;
+
+ if (fabs(lp_lat) <= TOL) { xy_x = lp_lon; xy_y = this->m_proj_parm.ml0; }
+ else {
+ cot = 1. / tan(lp_lat);
+ xy_x = sin(E = lp_lon * sin(lp_lat)) * cot;
+ xy_y = lp_lat - this->m_par.phi0 + cot * (1. - cos(E));
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double B, dphi, tp;
+ int i;
+
+ if (fabs(xy_y = this->m_par.phi0 + xy_y) <= TOL) { lp_lon = xy_x; lp_lat = 0.; }
+ else {
+ lp_lat = xy_y;
+ B = xy_x * xy_x + xy_y * xy_y;
+ i = N_ITER;
+ do {
+ tp = tan(lp_lat);
+ lp_lat -= (dphi = (xy_y * (lp_lat * tp + 1.) - lp_lat -
+ .5 * ( lp_lat * lp_lat + B) * tp) /
+ ((lp_lat - xy_y) / tp - 1.));
+ } while (fabs(dphi) > CONV && --i);
+ if (! i) throw proj_exception();;
+ lp_lon = asin(xy_x * tan(lp_lat)) / sin(lp_lat);
+ }
+ }
+ };
+
+ // Polyconic (American)
+ template <typename Parameters>
+ void setup_poly(Parameters& par, par_poly& proj_parm)
+ {
+ if (par.es) {
+ pj_enfn(par.es, proj_parm.en);
+ proj_parm.ml0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ proj_parm.ml0 = -par.phi0;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+ }} // namespace detail::poly
+ #endif // doxygen
+
+ /*!
+ \brief Polyconic (American) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_poly.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct poly_ellipsoid : public detail::poly::base_poly_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline poly_ellipsoid(const Parameters& par) : detail::poly::base_poly_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::poly::setup_poly(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Polyconic (American) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_poly.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct poly_spheroid : public detail::poly::base_poly_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline poly_spheroid(const Parameters& par) : detail::poly::base_poly_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::poly::setup_poly(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class poly_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<poly_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<poly_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void poly_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("poly", new poly_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_POLY_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/putp2.hpp b/src/boost/geometry/extensions/gis/projections/proj/putp2.hpp
new file mode 100644
index 0000000..2cadc58
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/putp2.hpp
@@ -0,0 +1,163 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace putp2{
+ static const double C_x = 1.89490;
+ static const double C_y = 1.71848;
+ static const double C_p = 0.6141848493043784;
+ static const double EPS = 1e-10;
+ static const int NITER = 10;
+ static const double PI_DIV_3 = 1.0471975511965977;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_putp2_spheroid : public base_t_fi<base_putp2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_putp2_spheroid(const Parameters& par)
+ : base_t_fi<base_putp2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double p, c, s, V;
+ int i;
+
+ p = C_p * sin(lp_lat);
+ s = lp_lat * lp_lat;
+ lp_lat *= 0.615709 + s * ( 0.00909953 + s * 0.0046292 );
+ for (i = NITER; i ; --i) {
+ c = cos(lp_lat);
+ s = sin(lp_lat);
+ lp_lat -= V = (lp_lat + s * (c - 1.) - p) /
+ (1. + c * (c - 1.) - s * s);
+ if (fabs(V) < EPS)
+ break;
+ }
+ if (!i)
+ lp_lat = lp_lat < 0 ? - PI_DIV_3 : PI_DIV_3;
+ xy_x = C_x * lp_lon * (cos(lp_lat) - 0.5);
+ xy_y = C_y * sin(lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double c;
+
+ lp_lat = aasin(xy_y / C_y);
+ lp_lon = xy_x / (C_x * ((c = cos(lp_lat)) - 0.5));
+ lp_lat = aasin((lp_lat + sin(lp_lat) * (c - 1.)) / C_p);
+ }
+ };
+
+ // Putnins P2
+ template <typename Parameters>
+ void setup_putp2(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::putp2
+ #endif // doxygen
+
+ /*!
+ \brief Putnins P2 projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp2.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp2_spheroid : public detail::putp2::base_putp2_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp2_spheroid(const Parameters& par) : detail::putp2::base_putp2_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp2::setup_putp2(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp2_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp2_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void putp2_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("putp2", new putp2_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP2_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/putp3.hpp b/src/boost/geometry/extensions/gis/projections/proj/putp3.hpp
new file mode 100644
index 0000000..36623ed
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/putp3.hpp
@@ -0,0 +1,197 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace putp3{
+ static const double C = 0.79788456;
+ static const double RPISQ = 0.1013211836;
+
+ struct par_putp3
+ {
+ double A;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_putp3_spheroid : public base_t_fi<base_putp3_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_putp3 m_proj_parm;
+
+ inline base_putp3_spheroid(const Parameters& par)
+ : base_t_fi<base_putp3_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = C * lp_lon * (1. - this->m_proj_parm.A * lp_lat * lp_lat);
+ xy_y = C * lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / C;
+ lp_lon = xy_x / (C * (1. - this->m_proj_parm.A * lp_lat * lp_lat));
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_putp3& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+
+ // Putnins P3
+ template <typename Parameters>
+ void setup_putp3(Parameters& par, par_putp3& proj_parm)
+ {
+ proj_parm.A = 4. * RPISQ;
+ setup(par, proj_parm);
+ }
+
+ // Putnins P3'
+ template <typename Parameters>
+ void setup_putp3p(Parameters& par, par_putp3& proj_parm)
+ {
+ proj_parm.A = 2. * RPISQ;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::putp3
+ #endif // doxygen
+
+ /*!
+ \brief Putnins P3 projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp3.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp3_spheroid : public detail::putp3::base_putp3_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp3_spheroid(const Parameters& par) : detail::putp3::base_putp3_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp3::setup_putp3(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Putnins P3' projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - no inverse
+ - Spheroid
+ \par Example
+ \image html ex_putp3p.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp3p_spheroid : public detail::putp3::base_putp3_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp3p_spheroid(const Parameters& par) : detail::putp3::base_putp3_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp3::setup_putp3p(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp3_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp3_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp3p_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp3p_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void putp3_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("putp3", new putp3_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("putp3p", new putp3p_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP3_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/putp4p.hpp b/src/boost/geometry/extensions/gis/projections/proj/putp4p.hpp
new file mode 100644
index 0000000..32bf3a5
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/putp4p.hpp
@@ -0,0 +1,201 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace putp4p{
+
+ struct par_putp4p
+ {
+ double C_x, C_y;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_putp4p_spheroid : public base_t_fi<base_putp4p_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_putp4p m_proj_parm;
+
+ inline base_putp4p_spheroid(const Parameters& par)
+ : base_t_fi<base_putp4p_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat = aasin(0.883883476 * sin(lp_lat));
+ xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat);
+ xy_x /= cos(lp_lat *= 0.333333333333333);
+ xy_y = this->m_proj_parm.C_y * sin(lp_lat);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = aasin(xy_y / this->m_proj_parm.C_y);
+ lp_lon = xy_x * cos(lp_lat) / this->m_proj_parm.C_x;
+ lp_lat *= 3.;
+ lp_lon /= cos(lp_lat);
+ lp_lat = aasin(1.13137085 * sin(lp_lat));
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_putp4p& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+
+ // Putnins P4'
+ template <typename Parameters>
+ void setup_putp4p(Parameters& par, par_putp4p& proj_parm)
+ {
+ proj_parm.C_x = 0.874038744;
+ proj_parm.C_y = 3.883251825;
+ setup(par, proj_parm);
+ }
+
+ // Werenskiold I
+ template <typename Parameters>
+ void setup_weren(Parameters& par, par_putp4p& proj_parm)
+ {
+ proj_parm.C_x = 1.;
+ proj_parm.C_y = 4.442882938;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::putp4p
+ #endif // doxygen
+
+ /*!
+ \brief Putnins P4' projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp4p.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp4p_spheroid : public detail::putp4p::base_putp4p_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp4p_spheroid(const Parameters& par) : detail::putp4p::base_putp4p_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp4p::setup_putp4p(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Werenskiold I projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_weren.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct weren_spheroid : public detail::putp4p::base_putp4p_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline weren_spheroid(const Parameters& par) : detail::putp4p::base_putp4p_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp4p::setup_weren(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp4p_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp4p_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class weren_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<weren_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void putp4p_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("putp4p", new putp4p_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("weren", new weren_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP4P_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/putp5.hpp b/src/boost/geometry/extensions/gis/projections/proj/putp5.hpp
new file mode 100644
index 0000000..959a0a1
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/putp5.hpp
@@ -0,0 +1,198 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace putp5{
+ static const double C = 1.01346;
+ static const double D = 1.2158542;
+
+ struct par_putp5
+ {
+ double A, B;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_putp5_spheroid : public base_t_fi<base_putp5_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_putp5 m_proj_parm;
+
+ inline base_putp5_spheroid(const Parameters& par)
+ : base_t_fi<base_putp5_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = C * lp_lon * (this->m_proj_parm.A - this->m_proj_parm.B * sqrt(1. + D * lp_lat * lp_lat));
+ xy_y = C * lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / C;
+ lp_lon = xy_x / (C * (this->m_proj_parm.A - this->m_proj_parm.B * sqrt(1. + D * lp_lat * lp_lat)));
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_putp5& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+
+ // Putnins P5
+ template <typename Parameters>
+ void setup_putp5(Parameters& par, par_putp5& proj_parm)
+ {
+ proj_parm.A = 2.;
+ proj_parm.B = 1.;
+ setup(par, proj_parm);
+ }
+
+ // Putnins P5'
+ template <typename Parameters>
+ void setup_putp5p(Parameters& par, par_putp5& proj_parm)
+ {
+ proj_parm.A = 1.5;
+ proj_parm.B = 0.5;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::putp5
+ #endif // doxygen
+
+ /*!
+ \brief Putnins P5 projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp5.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp5_spheroid : public detail::putp5::base_putp5_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp5_spheroid(const Parameters& par) : detail::putp5::base_putp5_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp5::setup_putp5(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Putnins P5' projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp5p.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp5p_spheroid : public detail::putp5::base_putp5_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp5p_spheroid(const Parameters& par) : detail::putp5::base_putp5_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp5::setup_putp5p(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp5_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp5_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp5p_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp5p_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void putp5_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("putp5", new putp5_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("putp5p", new putp5p_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP5_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/putp6.hpp b/src/boost/geometry/extensions/gis/projections/proj/putp6.hpp
new file mode 100644
index 0000000..425c8d9
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/putp6.hpp
@@ -0,0 +1,223 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace putp6{
+ static const double EPS = 1e-10;
+ static const int NITER = 10;
+ static const double CON_POLE = 1.732050807568877;
+
+ struct par_putp6
+ {
+ double C_x, C_y, A, B, D;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_putp6_spheroid : public base_t_fi<base_putp6_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_putp6 m_proj_parm;
+
+ inline base_putp6_spheroid(const Parameters& par)
+ : base_t_fi<base_putp6_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double p, r, V;
+ int i;
+
+ p = this->m_proj_parm.B * sin(lp_lat);
+ lp_lat *= 1.10265779;
+ for (i = NITER; i ; --i) {
+ r = sqrt(1. + lp_lat * lp_lat);
+ lp_lat -= V = ( (this->m_proj_parm.A - r) * lp_lat - log(lp_lat + r) - p ) /
+ (this->m_proj_parm.A - 2. * r);
+ if (fabs(V) < EPS)
+ break;
+ }
+ if (!i)
+ lp_lat = p < 0. ? -CON_POLE : CON_POLE;
+ xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.D - sqrt(1. + lp_lat * lp_lat));
+ xy_y = this->m_proj_parm.C_y * lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double r;
+
+ lp_lat = xy_y / this->m_proj_parm.C_y;
+ r = sqrt(1. + lp_lat * lp_lat);
+ lp_lon = xy_x / (this->m_proj_parm.C_x * (this->m_proj_parm.D - r));
+ lp_lat = aasin( ( (this->m_proj_parm.A - r) * lp_lat - log(lp_lat + r) ) / this->m_proj_parm.B);
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_putp6& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+
+ // Putnins P6
+ template <typename Parameters>
+ void setup_putp6(Parameters& par, par_putp6& proj_parm)
+ {
+ proj_parm.C_x = 1.01346;
+ proj_parm.C_y = 0.91910;
+ proj_parm.A = 4.;
+ proj_parm.B = 2.1471437182129378784;
+ proj_parm.D = 2.;
+ setup(par, proj_parm);
+ }
+
+ // Putnins P6'
+ template <typename Parameters>
+ void setup_putp6p(Parameters& par, par_putp6& proj_parm)
+ {
+ proj_parm.C_x = 0.44329;
+ proj_parm.C_y = 0.80404;
+ proj_parm.A = 6.;
+ proj_parm.B = 5.61125;
+ proj_parm.D = 3.;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::putp6
+ #endif // doxygen
+
+ /*!
+ \brief Putnins P6 projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp6.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp6_spheroid : public detail::putp6::base_putp6_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp6_spheroid(const Parameters& par) : detail::putp6::base_putp6_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp6::setup_putp6(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Putnins P6' projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_putp6p.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct putp6p_spheroid : public detail::putp6::base_putp6_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline putp6p_spheroid(const Parameters& par) : detail::putp6::base_putp6_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::putp6::setup_putp6p(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp6_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp6_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class putp6p_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<putp6p_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void putp6_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("putp6", new putp6_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("putp6p", new putp6p_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_PUTP6_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/robin.hpp b/src/boost/geometry/extensions/gis/projections/proj/robin.hpp
new file mode 100644
index 0000000..44bd2be
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/robin.hpp
@@ -0,0 +1,232 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/function_overloads.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace robin{
+ static const double FXC = 0.8487;
+ static const double FYC = 1.3523;
+ static const double C1 = 11.45915590261646417544;
+ static const double RC1 = 0.08726646259971647884;
+ static const int NODES = 18;
+ static const double ONEEPS = 1.000001;
+ static const double EPS = 1e-8;
+
+ /* note: following terms based upon 5 deg. intervals in degrees. */
+ static struct COEFS {
+ double c0, c1, c2, c3;
+ } X[] = {
+ {1, -5.67239e-12, -7.15511e-05, 3.11028e-06},
+ {0.9986, -0.000482241, -2.4897e-05, -1.33094e-06},
+ {0.9954, -0.000831031, -4.4861e-05, -9.86588e-07},
+ {0.99, -0.00135363, -5.96598e-05, 3.67749e-06},
+ {0.9822, -0.00167442, -4.4975e-06, -5.72394e-06},
+ {0.973, -0.00214869, -9.03565e-05, 1.88767e-08},
+ {0.96, -0.00305084, -9.00732e-05, 1.64869e-06},
+ {0.9427, -0.00382792, -6.53428e-05, -2.61493e-06},
+ {0.9216, -0.00467747, -0.000104566, 4.8122e-06},
+ {0.8962, -0.00536222, -3.23834e-05, -5.43445e-06},
+ {0.8679, -0.00609364, -0.0001139, 3.32521e-06},
+ {0.835, -0.00698325, -6.40219e-05, 9.34582e-07},
+ {0.7986, -0.00755337, -5.00038e-05, 9.35532e-07},
+ {0.7597, -0.00798325, -3.59716e-05, -2.27604e-06},
+ {0.7186, -0.00851366, -7.0112e-05, -8.63072e-06},
+ {0.6732, -0.00986209, -0.000199572, 1.91978e-05},
+ {0.6213, -0.010418, 8.83948e-05, 6.24031e-06},
+ {0.5722, -0.00906601, 0.000181999, 6.24033e-06},
+ {0.5322, 0.,0.,0. }},
+ Y[] = {
+ {0, 0.0124, 3.72529e-10, 1.15484e-09},
+ {0.062, 0.0124001, 1.76951e-08, -5.92321e-09},
+ {0.124, 0.0123998, -7.09668e-08, 2.25753e-08},
+ {0.186, 0.0124008, 2.66917e-07, -8.44523e-08},
+ {0.248, 0.0123971, -9.99682e-07, 3.15569e-07},
+ {0.31, 0.0124108, 3.73349e-06, -1.1779e-06},
+ {0.372, 0.0123598, -1.3935e-05, 4.39588e-06},
+ {0.434, 0.0125501, 5.20034e-05, -1.00051e-05},
+ {0.4968, 0.0123198, -9.80735e-05, 9.22397e-06},
+ {0.5571, 0.0120308, 4.02857e-05, -5.2901e-06},
+ {0.6176, 0.0120369, -3.90662e-05, 7.36117e-07},
+ {0.6769, 0.0117015, -2.80246e-05, -8.54283e-07},
+ {0.7346, 0.0113572, -4.08389e-05, -5.18524e-07},
+ {0.7903, 0.0109099, -4.86169e-05, -1.0718e-06},
+ {0.8435, 0.0103433, -6.46934e-05, 5.36384e-09},
+ {0.8936, 0.00969679, -6.46129e-05, -8.54894e-06},
+ {0.9394, 0.00840949, -0.000192847, -4.21023e-06},
+ {0.9761, 0.00616525, -0.000256001, -4.21021e-06},
+ {1., 0.,0.,0 }};
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_robin_spheroid : public base_t_fi<base_robin_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_robin_spheroid(const Parameters& par)
+ : base_t_fi<base_robin_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline double V(COEFS const& C, double z) const
+ { return (C.c0 + z * (C.c1 + z * (C.c2 + z * C.c3))); }
+ inline double DV(COEFS const& C, double z) const
+ { return (C.c1 + z * (C.c2 + C.c2 + z * 3. * C.c3)); }
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ int i;
+ double dphi;
+
+ i = int_floor((dphi = fabs(lp_lat)) * C1);
+ if (i >= NODES) i = NODES - 1;
+ dphi = RAD_TO_DEG * (dphi - RC1 * i);
+ xy_x = V(X[i], dphi) * FXC * lp_lon;
+ xy_y = V(Y[i], dphi) * FYC;
+ if (lp_lat < 0.) xy_y = -xy_y;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ int i;
+ double t, t1;
+ struct COEFS T;
+
+ lp_lon = xy_x / FXC;
+ lp_lat = fabs(xy_y / FYC);
+ if (lp_lat >= 1.) { /* simple pathologic cases */
+ if (lp_lat > ONEEPS) throw proj_exception();
+ else {
+ lp_lat = xy_y < 0. ? -HALFPI : HALFPI;
+ lp_lon /= X[NODES].c0;
+ }
+ } else { /* general problem */
+ /* in Y space, reduce to table interval */
+ for (i = int_floor(lp_lat * NODES);;) {
+ if (Y[i].c0 > lp_lat) --i;
+ else if (Y[i+1].c0 <= lp_lat) ++i;
+ else break;
+ }
+ T = Y[i];
+ /* first guess, linear interp */
+ t = 5. * (lp_lat - T.c0)/(Y[i+1].c0 - T.c0);
+ /* make into root */
+ T.c0 -= lp_lat;
+ for (;;) { /* Newton-Raphson reduction */
+ t -= t1 = V(T,t) / DV(T,t);
+ if (fabs(t1) < EPS)
+ break;
+ }
+ lp_lat = (5 * i + t) * DEG_TO_RAD;
+ if (xy_y < 0.) lp_lat = -lp_lat;
+ lp_lon /= V(X[i], t);
+ }
+ }
+ };
+
+ // Robinson
+ template <typename Parameters>
+ void setup_robin(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::robin
+ #endif // doxygen
+
+ /*!
+ \brief Robinson projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_robin.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct robin_spheroid : public detail::robin::base_robin_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline robin_spheroid(const Parameters& par) : detail::robin::base_robin_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::robin::setup_robin(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class robin_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<robin_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void robin_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("robin", new robin_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ROBIN_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/rouss.hpp b/src/boost/geometry/extensions/gis/projections/proj/rouss.hpp
new file mode 100644
index 0000000..5813d49
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/rouss.hpp
@@ -0,0 +1,211 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/proj_mdist.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace rouss{
+
+ struct par_rouss
+ {
+ double s0;
+ double A1, A2, A3, A4, A5, A6;
+ double B1, B2, B3, B4, B5, B6, B7, B8;
+ double C1, C2, C3, C4, C5, C6, C7, C8;
+ double D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11;
+ MDIST en;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_rouss_ellipsoid : public base_t_fi<base_rouss_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_rouss m_proj_parm;
+
+ inline base_rouss_ellipsoid(const Parameters& par)
+ : base_t_fi<base_rouss_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double s, al, cp, sp, al2, s2;
+
+ cp = cos(lp_lat);
+ sp = sin(lp_lat);
+ s = proj_mdist(lp_lat, sp, cp, this->m_proj_parm.en) - this->m_proj_parm.s0;
+ s2 = s * s;
+ al = lp_lon * cp / sqrt(1. - this->m_par.es * sp * sp);
+ al2 = al * al;
+ xy_x = this->m_par.k0 * al*(1.+s2*(this->m_proj_parm.A1+s2*this->m_proj_parm.A4)-al2*(this->m_proj_parm.A2+s*this->m_proj_parm.A3+s2*this->m_proj_parm.A5
+ +al2*this->m_proj_parm.A6));
+ xy_y = this->m_par.k0 * (al2*(this->m_proj_parm.B1+al2*this->m_proj_parm.B4)+
+ s*(1.+al2*(this->m_proj_parm.B3-al2*this->m_proj_parm.B6)+s2*(this->m_proj_parm.B2+s2*this->m_proj_parm.B8)+
+ s*al2*(this->m_proj_parm.B5+s*this->m_proj_parm.B7)));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double s, al, x = xy_x / this->m_par.k0, y = xy_y / this->m_par.k0, x2, y2;;
+
+ x2 = x * x;
+ y2 = y * y;
+ al = x*(1.-this->m_proj_parm.C1*y2+x2*(this->m_proj_parm.C2+this->m_proj_parm.C3*y-this->m_proj_parm.C4*x2+this->m_proj_parm.C5*y2-this->m_proj_parm.C7*x2*y)
+ +y2*(this->m_proj_parm.C6*y2-this->m_proj_parm.C8*x2*y));
+ s = this->m_proj_parm.s0 + y*(1.+y2*(-this->m_proj_parm.D2+this->m_proj_parm.D8*y2))+
+ x2*(-this->m_proj_parm.D1+y*(-this->m_proj_parm.D3+y*(-this->m_proj_parm.D5+y*(-this->m_proj_parm.D7+y*this->m_proj_parm.D11)))+
+ x2*(this->m_proj_parm.D4+y*(this->m_proj_parm.D6+y*this->m_proj_parm.D10)-x2*this->m_proj_parm.D9));
+ lp_lat=proj_inv_mdist(s, this->m_proj_parm.en);
+ s = sin(lp_lat);
+ lp_lon=al * sqrt(1. - this->m_par.es * s * s)/cos(lp_lat);
+ }
+ };
+
+ // Roussilhe Stereographic
+ template <typename Parameters>
+ void setup_rouss(Parameters& par, par_rouss& proj_parm)
+ {
+ double N0, es2, t, t2, R_R0_2, R_R0_4;
+ proj_mdist_ini(par.es, proj_parm.en);
+
+ es2 = sin(par.phi0);
+ proj_parm.s0 = proj_mdist(par.phi0, es2, cos(par.phi0), proj_parm.en);
+ t = 1. - (es2 = par.es * es2 * es2);
+ N0 = 1./sqrt(t);
+ R_R0_2 = t * t / par.one_es;
+ R_R0_4 = R_R0_2 * R_R0_2;
+ t = tan(par.phi0);
+ t2 = t * t;
+ proj_parm.C1 = proj_parm.A1 = R_R0_2 / 4.;
+ proj_parm.C2 = proj_parm.A2 = R_R0_2 * (2 * t2 - 1. - 2. * es2) / 12.;
+ proj_parm.A3 = R_R0_2 * t * (1. + 4. * t2)/ ( 12. * N0);
+ proj_parm.A4 = R_R0_4 / 24.;
+ proj_parm.A5 = R_R0_4 * ( -1. + t2 * (11. + 12. * t2))/24.;
+ proj_parm.A6 = R_R0_4 * ( -2. + t2 * (11. - 2. * t2))/240.;
+ proj_parm.B1 = t / (2. * N0);
+ proj_parm.B2 = R_R0_2 / 12.;
+ proj_parm.B3 = R_R0_2 * (1. + 2. * t2 - 2. * es2)/4.;
+ proj_parm.B4 = R_R0_2 * t * (2. - t2)/(24. * N0);
+ proj_parm.B5 = R_R0_2 * t * (5. + 4.* t2)/(8. * N0);
+ proj_parm.B6 = R_R0_4 * (-2. + t2 * (-5. + 6. * t2))/48.;
+ proj_parm.B7 = R_R0_4 * (5. + t2 * (19. + 12. * t2))/24.;
+ proj_parm.B8 = R_R0_4 / 120.;
+ proj_parm.C3 = R_R0_2 * t * (1. + t2)/(3. * N0);
+ proj_parm.C4 = R_R0_4 * (-3. + t2 * (34. + 22. * t2))/240.;
+ proj_parm.C5 = R_R0_4 * (4. + t2 * (13. + 12. * t2))/24.;
+ proj_parm.C6 = R_R0_4 / 16.;
+ proj_parm.C7 = R_R0_4 * t * (11. + t2 * (33. + t2 * 16.))/(48. * N0);
+ proj_parm.C8 = R_R0_4 * t * (1. + t2 * 4.)/(36. * N0);
+ proj_parm.D1 = t / (2. * N0);
+ proj_parm.D2 = R_R0_2 / 12.;
+ proj_parm.D3 = R_R0_2 * (2 * t2 + 1. - 2. * es2) / 4.;
+ proj_parm.D4 = R_R0_2 * t * (1. + t2)/(8. * N0);
+ proj_parm.D5 = R_R0_2 * t * (1. + t2 * 2.)/(4. * N0);
+ proj_parm.D6 = R_R0_4 * (1. + t2 * (6. + t2 * 6.))/16.;
+ proj_parm.D7 = R_R0_4 * t2 * (3. + t2 * 4.)/8.;
+ proj_parm.D8 = R_R0_4 / 80.;
+ proj_parm.D9 = R_R0_4 * t * (-21. + t2 * (178. - t2 * 26.))/720.;
+ proj_parm.D10 = R_R0_4 * t * (29. + t2 * (86. + t2 * 48.))/(96. * N0);
+ proj_parm.D11 = R_R0_4 * t * (37. + t2 * 44.)/(96. * N0);
+ // par.fwd = e_forward;
+ // par.inv = e_inverse;
+ }
+
+ }} // namespace detail::rouss
+ #endif // doxygen
+
+ /*!
+ \brief Roussilhe Stereographic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Ellps
+ \par Example
+ \image html ex_rouss.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct rouss_ellipsoid : public detail::rouss::base_rouss_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline rouss_ellipsoid(const Parameters& par) : detail::rouss::base_rouss_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::rouss::setup_rouss(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class rouss_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<rouss_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void rouss_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("rouss", new rouss_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_ROUSS_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/rpoly.hpp b/src/boost/geometry/extensions/gis/projections/proj/rpoly.hpp
new file mode 100644
index 0000000..1dc8087
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/rpoly.hpp
@@ -0,0 +1,158 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace rpoly{
+ static const double EPS = 1e-9;
+
+ struct par_rpoly
+ {
+ double phi1;
+ double fxa;
+ double fxb;
+ int mode;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_rpoly_spheroid : public base_t_f<base_rpoly_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_rpoly m_proj_parm;
+
+ inline base_rpoly_spheroid(const Parameters& par)
+ : base_t_f<base_rpoly_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double fa;
+
+ if (this->m_proj_parm.mode)
+ fa = tan(lp_lon * this->m_proj_parm.fxb) * this->m_proj_parm.fxa;
+ else
+ fa = 0.5 * lp_lon;
+ if (fabs(lp_lat) < EPS) {
+ xy_x = fa + fa;
+ xy_y = - this->m_par.phi0;
+ } else {
+ xy_y = 1. / tan(lp_lat);
+ xy_x = sin(fa = 2. * atan(fa * sin(lp_lat))) * xy_y;
+ xy_y = lp_lat - this->m_par.phi0 + (1. - cos(fa)) * xy_y;
+ }
+ }
+ };
+
+ // Rectangular Polyconic
+ template <typename Parameters>
+ void setup_rpoly(Parameters& par, par_rpoly& proj_parm)
+ {
+ if ((proj_parm.mode = (proj_parm.phi1 = fabs(pj_param(par.params, "rlat_ts").f)) > EPS)) {
+ proj_parm.fxb = 0.5 * sin(proj_parm.phi1);
+ proj_parm.fxa = 0.5 / proj_parm.fxb;
+ }
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::rpoly
+ #endif // doxygen
+
+ /*!
+ \brief Rectangular Polyconic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - no inverse
+ - lat_ts=
+ \par Example
+ \image html ex_rpoly.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct rpoly_spheroid : public detail::rpoly::base_rpoly_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline rpoly_spheroid(const Parameters& par) : detail::rpoly::base_rpoly_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::rpoly::setup_rpoly(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class rpoly_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<rpoly_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void rpoly_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("rpoly", new rpoly_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_RPOLY_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/sconics.hpp b/src/boost/geometry/extensions/gis/projections/proj/sconics.hpp
new file mode 100644
index 0000000..cf75ff1
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/sconics.hpp
@@ -0,0 +1,511 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace sconics{
+ static const int EULER = 0;
+ static const int MURD1 = 1;
+ static const int MURD2 = 2;
+ static const int MURD3 = 3;
+ static const int PCONIC = 4;
+ static const int TISSOT = 5;
+ static const int VITK1 = 6;
+ static const double EPS10 = 1.e-10;
+ static const double EPS = 1e-10;
+
+ struct par_sconics
+ {
+ double n;
+ double rho_c;
+ double rho_0;
+ double sig;
+ double c1, c2;
+ int type;
+ };
+ /* get common factors for simple conics */
+ template <typename Parameters>
+ inline int
+ phi12(Parameters& par, par_sconics& proj_parm, double *del) {
+ double p1, p2;
+ int err = 0;
+
+ if (!pj_param(par.params, "tlat_1").i ||
+ !pj_param(par.params, "tlat_2").i) {
+ err = -41;
+ } else {
+ p1 = pj_param(par.params, "rlat_1").f;
+ p2 = pj_param(par.params, "rlat_2").f;
+ *del = 0.5 * (p2 - p1);
+ proj_parm.sig = 0.5 * (p2 + p1);
+ err = (fabs(*del) < EPS || fabs(proj_parm.sig) < EPS) ? -42 : 0;
+ *del = *del;
+ }
+ return err;
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_sconics_spheroid : public base_t_fi<base_sconics_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_sconics m_proj_parm;
+
+ inline base_sconics_spheroid(const Parameters& par)
+ : base_t_fi<base_sconics_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double rho;
+
+ switch (this->m_proj_parm.type) {
+ case MURD2:
+ rho = this->m_proj_parm.rho_c + tan(this->m_proj_parm.sig - lp_lat);
+ break;
+ case PCONIC:
+ rho = this->m_proj_parm.c2 * (this->m_proj_parm.c1 - tan(lp_lat - this->m_proj_parm.sig));
+ break;
+ default:
+ rho = this->m_proj_parm.rho_c - lp_lat;
+ break;
+ }
+ xy_x = rho * sin( lp_lon *= this->m_proj_parm.n );
+ xy_y = this->m_proj_parm.rho_0 - rho * cos(lp_lon);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rho;
+
+ rho = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.rho_0 - xy_y);
+ if (this->m_proj_parm.n < 0.) {
+ rho = - rho;
+ xy_x = - xy_x;
+ xy_y = - xy_y;
+ }
+ lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n;
+ switch (this->m_proj_parm.type) {
+ case PCONIC:
+ lp_lat = atan(this->m_proj_parm.c1 - rho / this->m_proj_parm.c2) + this->m_proj_parm.sig;
+ break;
+ case MURD2:
+ lp_lat = this->m_proj_parm.sig - atan(rho - this->m_proj_parm.rho_c);
+ break;
+ default:
+ lp_lat = this->m_proj_parm.rho_c - rho;
+ }
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_sconics& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ double del, cs;
+ int i;
+ if( (i = phi12(par, proj_parm, &del)) )
+ throw proj_exception(i);
+ switch (proj_parm.type) {
+ case TISSOT:
+ proj_parm.n = sin(proj_parm.sig);
+ cs = cos(del);
+ proj_parm.rho_c = proj_parm.n / cs + cs / proj_parm.n;
+ proj_parm.rho_0 = sqrt((proj_parm.rho_c - 2 * sin(par.phi0))/proj_parm.n);
+ break;
+ case MURD1:
+ proj_parm.rho_c = sin(del)/(del * tan(proj_parm.sig)) + proj_parm.sig;
+ proj_parm.rho_0 = proj_parm.rho_c - par.phi0;
+ proj_parm.n = sin(proj_parm.sig);
+ break;
+ case MURD2:
+ proj_parm.rho_c = (cs = sqrt(cos(del))) / tan(proj_parm.sig);
+ proj_parm.rho_0 = proj_parm.rho_c + tan(proj_parm.sig - par.phi0);
+ proj_parm.n = sin(proj_parm.sig) * cs;
+ break;
+ case MURD3:
+ proj_parm.rho_c = del / (tan(proj_parm.sig) * tan(del)) + proj_parm.sig;
+ proj_parm.rho_0 = proj_parm.rho_c - par.phi0;
+ proj_parm.n = sin(proj_parm.sig) * sin(del) * tan(del) / (del * del);
+ break;
+ case EULER:
+ proj_parm.n = sin(proj_parm.sig) * sin(del) / del;
+ del *= 0.5;
+ proj_parm.rho_c = del / (tan(del) * tan(proj_parm.sig)) + proj_parm.sig;
+ proj_parm.rho_0 = proj_parm.rho_c - par.phi0;
+ break;
+ case PCONIC:
+ proj_parm.n = sin(proj_parm.sig);
+ proj_parm.c2 = cos(del);
+ proj_parm.c1 = 1./tan(proj_parm.sig);
+ if (fabs(del = par.phi0 - proj_parm.sig) - EPS10 >= HALFPI)
+ throw proj_exception(-43);
+ proj_parm.rho_0 = proj_parm.c2 * (proj_parm.c1 - tan(del));
+ break;
+ case VITK1:
+ proj_parm.n = (cs = tan(del)) * sin(proj_parm.sig) / del;
+ proj_parm.rho_c = del / (cs * tan(proj_parm.sig)) + proj_parm.sig;
+ proj_parm.rho_0 = proj_parm.rho_c - par.phi0;
+ break;
+ }
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0;
+ }
+
+
+ // Tissot
+ template <typename Parameters>
+ void setup_tissot(Parameters& par, par_sconics& proj_parm)
+ {
+ proj_parm.type = TISSOT;
+ setup(par, proj_parm);
+ }
+
+ // Murdoch I
+ template <typename Parameters>
+ void setup_murd1(Parameters& par, par_sconics& proj_parm)
+ {
+ proj_parm.type = MURD1;
+ setup(par, proj_parm);
+ }
+
+ // Murdoch II
+ template <typename Parameters>
+ void setup_murd2(Parameters& par, par_sconics& proj_parm)
+ {
+ proj_parm.type = MURD2;
+ setup(par, proj_parm);
+ }
+
+ // Murdoch III
+ template <typename Parameters>
+ void setup_murd3(Parameters& par, par_sconics& proj_parm)
+ {
+ proj_parm.type = MURD3;
+ setup(par, proj_parm);
+ }
+
+ // Euler
+ template <typename Parameters>
+ void setup_euler(Parameters& par, par_sconics& proj_parm)
+ {
+ proj_parm.type = EULER;
+ setup(par, proj_parm);
+ }
+
+ // Perspective Conic
+ template <typename Parameters>
+ void setup_pconic(Parameters& par, par_sconics& proj_parm)
+ {
+ proj_parm.type = PCONIC;
+ setup(par, proj_parm);
+ }
+
+ // Vitkovsky I
+ template <typename Parameters>
+ void setup_vitk1(Parameters& par, par_sconics& proj_parm)
+ {
+ proj_parm.type = VITK1;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::sconics
+ #endif // doxygen
+
+ /*!
+ \brief Tissot projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - lat_1= and lat_2=
+ \par Example
+ \image html ex_tissot.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct tissot_spheroid : public detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline tissot_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sconics::setup_tissot(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Murdoch I projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - lat_1= and lat_2=
+ \par Example
+ \image html ex_murd1.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct murd1_spheroid : public detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline murd1_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sconics::setup_murd1(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Murdoch II projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - lat_1= and lat_2=
+ \par Example
+ \image html ex_murd2.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct murd2_spheroid : public detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline murd2_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sconics::setup_murd2(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Murdoch III projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - lat_1= and lat_2=
+ \par Example
+ \image html ex_murd3.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct murd3_spheroid : public detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline murd3_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sconics::setup_murd3(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Euler projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - lat_1= and lat_2=
+ \par Example
+ \image html ex_euler.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct euler_spheroid : public detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline euler_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sconics::setup_euler(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Perspective Conic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - lat_1= and lat_2=
+ \par Example
+ \image html ex_pconic.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct pconic_spheroid : public detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline pconic_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sconics::setup_pconic(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Vitkovsky I projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Conic
+ - Spheroid
+ - lat_1= and lat_2=
+ \par Example
+ \image html ex_vitk1.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct vitk1_spheroid : public detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline vitk1_spheroid(const Parameters& par) : detail::sconics::base_sconics_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sconics::setup_vitk1(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class tissot_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<tissot_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class murd1_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<murd1_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class murd2_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<murd2_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class murd3_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<murd3_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class euler_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<euler_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class pconic_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<pconic_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class vitk1_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<vitk1_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void sconics_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("tissot", new tissot_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("murd1", new murd1_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("murd2", new murd2_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("murd3", new murd3_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("euler", new euler_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("pconic", new pconic_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("vitk1", new vitk1_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_SCONICS_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/somerc.hpp b/src/boost/geometry/extensions/gis/projections/proj/somerc.hpp
new file mode 100644
index 0000000..c73e315
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/somerc.hpp
@@ -0,0 +1,188 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace somerc{
+ static const double EPS = 1.e-10;
+ static const int NITER = 6;
+
+ struct par_somerc
+ {
+ double K, c, hlf_e, kR, cosp0, sinp0;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_somerc_ellipsoid : public base_t_fi<base_somerc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_somerc m_proj_parm;
+
+ inline base_somerc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_somerc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double phip, lamp, phipp, lampp, sp, cp;
+
+ sp = this->m_par.e * sin(lp_lat);
+ phip = 2.* atan( exp( this->m_proj_parm.c * (
+ log(tan(FORTPI + 0.5 * lp_lat)) - this->m_proj_parm.hlf_e * log((1. + sp)/(1. - sp)))
+ + this->m_proj_parm.K)) - HALFPI;
+ lamp = this->m_proj_parm.c * lp_lon;
+ cp = cos(phip);
+ phipp = aasin(this->m_proj_parm.cosp0 * sin(phip) - this->m_proj_parm.sinp0 * cp * cos(lamp));
+ lampp = aasin(cp * sin(lamp) / cos(phipp));
+ xy_x = this->m_proj_parm.kR * lampp;
+ xy_y = this->m_proj_parm.kR * log(tan(FORTPI + 0.5 * phipp));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double phip, lamp, phipp, lampp, cp, esp, con, delp;
+ int i;
+
+ phipp = 2. * (atan(exp(xy_y / this->m_proj_parm.kR)) - FORTPI);
+ lampp = xy_x / this->m_proj_parm.kR;
+ cp = cos(phipp);
+ phip = aasin(this->m_proj_parm.cosp0 * sin(phipp) + this->m_proj_parm.sinp0 * cp * cos(lampp));
+ lamp = aasin(cp * sin(lampp) / cos(phip));
+ con = (this->m_proj_parm.K - log(tan(FORTPI + 0.5 * phip)))/this->m_proj_parm.c;
+ for (i = NITER; i ; --i) {
+ esp = this->m_par.e * sin(phip);
+ delp = (con + log(tan(FORTPI + 0.5 * phip)) - this->m_proj_parm.hlf_e *
+ log((1. + esp)/(1. - esp)) ) *
+ (1. - esp * esp) * cos(phip) * this->m_par.rone_es;
+ phip -= delp;
+ if (fabs(delp) < EPS)
+ break;
+ }
+ if (i) {
+ lp_lat = phip;
+ lp_lon = lamp / this->m_proj_parm.c;
+ } else
+ throw proj_exception();
+ }
+ };
+
+ // Swiss. Obl. Mercator
+ template <typename Parameters>
+ void setup_somerc(Parameters& par, par_somerc& proj_parm)
+ {
+ double cp, phip0, sp;
+ proj_parm.hlf_e = 0.5 * par.e;
+ cp = cos(par.phi0);
+ cp *= cp;
+ proj_parm.c = sqrt(1 + par.es * cp * cp * par.rone_es);
+ sp = sin(par.phi0);
+ proj_parm.cosp0 = cos( phip0 = aasin(proj_parm.sinp0 = sp / proj_parm.c) );
+ sp *= par.e;
+ proj_parm.K = log(tan(FORTPI + 0.5 * phip0)) - proj_parm.c * (
+ log(tan(FORTPI + 0.5 * par.phi0)) - proj_parm.hlf_e *
+ log((1. + sp) / (1. - sp)));
+ proj_parm.kR = par.k0 * sqrt(par.one_es) / (1. - sp * sp);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+ }} // namespace detail::somerc
+ #endif // doxygen
+
+ /*!
+ \brief Swiss. Obl. Mercator projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Ellipsoid
+ - For CH1903
+ \par Example
+ \image html ex_somerc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct somerc_ellipsoid : public detail::somerc::base_somerc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline somerc_ellipsoid(const Parameters& par) : detail::somerc::base_somerc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::somerc::setup_somerc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class somerc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<somerc_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void somerc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("somerc", new somerc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/stere.hpp b/src/boost/geometry/extensions/gis/projections/proj/stere.hpp
new file mode 100644
index 0000000..18183d9
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/stere.hpp
@@ -0,0 +1,451 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_STERE_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_STERE_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_tsfn.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace stere{
+ static const double EPS10 = 1.e-10;
+ static const double TOL = 1.e-8;
+ static const int NITER = 8;
+ static const double CONV = 1.e-10;
+ static const int S_POLE = 0;
+ static const int N_POLE = 1;
+ static const int OBLIQ = 2;
+ static const int EQUIT = 3;
+
+ struct par_stere
+ {
+ double phits;
+ double sinX1;
+ double cosX1;
+ double akm1;
+ int mode;
+ };
+ inline double
+ ssfn_(double phit, double sinphi, double eccen) {
+ sinphi *= eccen;
+ return (tan (.5 * (HALFPI + phit)) *
+ pow((1. - sinphi) / (1. + sinphi), .5 * eccen));
+ }
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_stere_ellipsoid : public base_t_fi<base_stere_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_stere m_proj_parm;
+
+ inline base_stere_ellipsoid(const Parameters& par)
+ : base_t_fi<base_stere_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double coslam, sinlam, sinX=0.0, cosX=0.0, X, A, sinphi;
+
+ coslam = cos(lp_lon);
+ sinlam = sin(lp_lon);
+ sinphi = sin(lp_lat);
+ if (this->m_proj_parm.mode == OBLIQ || this->m_proj_parm.mode == EQUIT) {
+ sinX = sin(X = 2. * atan(ssfn_(lp_lat, sinphi, this->m_par.e)) - HALFPI);
+ cosX = cos(X);
+ }
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ A = this->m_proj_parm.akm1 / (this->m_proj_parm.cosX1 * (1. + this->m_proj_parm.sinX1 * sinX +
+ this->m_proj_parm.cosX1 * cosX * coslam));
+ xy_y = A * (this->m_proj_parm.cosX1 * sinX - this->m_proj_parm.sinX1 * cosX * coslam);
+ goto xmul;
+ case EQUIT:
+ A = 2. * this->m_proj_parm.akm1 / (1. + cosX * coslam);
+ xy_y = A * sinX;
+ xmul:
+ xy_x = A * cosX;
+ break;
+ case S_POLE:
+ lp_lat = -lp_lat;
+ coslam = - coslam;
+ sinphi = -sinphi;
+ case N_POLE:
+ xy_x = this->m_proj_parm.akm1 * pj_tsfn(lp_lat, sinphi, this->m_par.e);
+ xy_y = - xy_x * coslam;
+ break;
+ }
+ xy_x = xy_x * sinlam;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, halfpi=0.0;
+ int i;
+
+ rho = boost::math::hypot(xy_x, xy_y);
+ switch (this->m_proj_parm.mode) {
+ case OBLIQ:
+ case EQUIT:
+ cosphi = cos( tp = 2. * atan2(rho * this->m_proj_parm.cosX1 , this->m_proj_parm.akm1) );
+ sinphi = sin(tp);
+ if( rho == 0.0 )
+ phi_l = asin(cosphi * this->m_proj_parm.sinX1);
+ else
+ phi_l = asin(cosphi * this->m_proj_parm.sinX1 + (xy_y * sinphi * this->m_proj_parm.cosX1 / rho));
+
+ tp = tan(.5 * (HALFPI + phi_l));
+ xy_x *= sinphi;
+ xy_y = rho * this->m_proj_parm.cosX1 * cosphi - xy_y * this->m_proj_parm.sinX1* sinphi;
+ halfpi = HALFPI;
+ halfe = .5 * this->m_par.e;
+ break;
+ case N_POLE:
+ xy_y = -xy_y;
+ case S_POLE:
+ phi_l = HALFPI - 2. * atan(tp = - rho / this->m_proj_parm.akm1);
+ halfpi = -HALFPI;
+ halfe = -.5 * this->m_par.e;
+ break;
+ }
+ for (i = NITER; i--; phi_l = lp_lat) {
+ sinphi = this->m_par.e * sin(phi_l);
+ lp_lat = 2. * atan(tp * pow((1.+sinphi)/(1.-sinphi),
+ halfe)) - halfpi;
+ if (fabs(phi_l - lp_lat) < CONV) {
+ if (this->m_proj_parm.mode == S_POLE)
+ lp_lat = -lp_lat;
+ lp_lon = (xy_x == 0. && xy_y == 0.) ? 0. : atan2(xy_x, xy_y);
+ return;
+ }
+ }
+ throw proj_exception();;
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_stere_spheroid : public base_t_fi<base_stere_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_stere m_proj_parm;
+
+ inline base_stere_spheroid(const Parameters& par)
+ : base_t_fi<base_stere_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double sinphi, cosphi, coslam, sinlam;
+
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ coslam = cos(lp_lon);
+ sinlam = sin(lp_lon);
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ xy_y = 1. + cosphi * coslam;
+ goto oblcon;
+ case OBLIQ:
+ xy_y = 1. + this->m_proj_parm.sinX1 * sinphi + this->m_proj_parm.cosX1 * cosphi * coslam;
+ oblcon:
+ if (xy_y <= EPS10) throw proj_exception();;
+ xy_x = (xy_y = this->m_proj_parm.akm1 / xy_y) * cosphi * sinlam;
+ xy_y *= (this->m_proj_parm.mode == EQUIT) ? sinphi :
+ this->m_proj_parm.cosX1 * sinphi - this->m_proj_parm.sinX1 * cosphi * coslam;
+ break;
+ case N_POLE:
+ coslam = - coslam;
+ lp_lat = - lp_lat;
+ case S_POLE:
+ if (fabs(lp_lat - HALFPI) < TOL) throw proj_exception();;
+ xy_x = sinlam * ( xy_y = this->m_proj_parm.akm1 * tan(FORTPI + .5 * lp_lat) );
+ xy_y *= coslam;
+ break;
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double c, rh, sinc, cosc;
+
+ sinc = sin(c = 2. * atan((rh = boost::math::hypot(xy_x, xy_y)) / this->m_proj_parm.akm1));
+ cosc = cos(c);
+ lp_lon = 0.;
+ switch (this->m_proj_parm.mode) {
+ case EQUIT:
+ if (fabs(rh) <= EPS10)
+ lp_lat = 0.;
+ else
+ lp_lat = asin(xy_y * sinc / rh);
+ if (cosc != 0. || xy_x != 0.)
+ lp_lon = atan2(xy_x * sinc, cosc * rh);
+ break;
+ case OBLIQ:
+ if (fabs(rh) <= EPS10)
+ lp_lat = this->m_par.phi0;
+ else
+ lp_lat = asin(cosc * this->m_proj_parm.sinX1 + xy_y * sinc * this->m_proj_parm.cosX1 / rh);
+ if ((c = cosc - this->m_proj_parm.sinX1 * sin(lp_lat)) != 0. || xy_x != 0.)
+ lp_lon = atan2(xy_x * sinc * this->m_proj_parm.cosX1, c * rh);
+ break;
+ case N_POLE:
+ xy_y = -xy_y;
+ case S_POLE:
+ if (fabs(rh) <= EPS10)
+ lp_lat = this->m_par.phi0;
+ else
+ lp_lat = asin(this->m_proj_parm.mode == S_POLE ? - cosc : cosc);
+ lp_lon = (xy_x == 0. && xy_y == 0.) ? 0. : atan2(xy_x, xy_y);
+ break;
+ }
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_stere& proj_parm) /* general initialization */
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ double t;
+ if (fabs((t = fabs(par.phi0)) - HALFPI) < EPS10)
+ proj_parm.mode = par.phi0 < 0. ? S_POLE : N_POLE;
+ else
+ proj_parm.mode = t > EPS10 ? OBLIQ : EQUIT;
+ proj_parm.phits = fabs(proj_parm.phits);
+ if (par.es) {
+ double X;
+ switch (proj_parm.mode) {
+ case N_POLE:
+ case S_POLE:
+ if (fabs(proj_parm.phits - HALFPI) < EPS10)
+ proj_parm.akm1 = 2. * par.k0 /
+ sqrt(pow(1+par.e,1+par.e)*pow(1-par.e,1-par.e));
+ else {
+ proj_parm.akm1 = cos(proj_parm.phits) /
+ pj_tsfn(proj_parm.phits, t = sin(proj_parm.phits), par.e);
+ t *= par.e;
+ proj_parm.akm1 /= sqrt(1. - t * t);
+ }
+ break;
+ case EQUIT:
+ proj_parm.akm1 = 2. * par.k0;
+ break;
+ case OBLIQ:
+ t = sin(par.phi0);
+ X = 2. * atan(ssfn_(par.phi0, t, par.e)) - HALFPI;
+ t *= par.e;
+ proj_parm.akm1 = 2. * par.k0 * cos(par.phi0) / sqrt(1. - t * t);
+ proj_parm.sinX1 = sin(X);
+ proj_parm.cosX1 = cos(X);
+ break;
+ }
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ switch (proj_parm.mode) {
+ case OBLIQ:
+ proj_parm.sinX1 = sin(par.phi0);
+ proj_parm.cosX1 = cos(par.phi0);
+ case EQUIT:
+ proj_parm.akm1 = 2. * par.k0;
+ break;
+ case S_POLE:
+ case N_POLE:
+ proj_parm.akm1 = fabs(proj_parm.phits - HALFPI) >= EPS10 ?
+ cos(proj_parm.phits) / tan(FORTPI - .5 * proj_parm.phits) :
+ 2. * par.k0 ;
+ break;
+ }
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+
+ // Stereographic
+ template <typename Parameters>
+ void setup_stere(Parameters& par, par_stere& proj_parm)
+ {
+ proj_parm.phits = pj_param(par.params, "tlat_ts").i ?
+ pj_param(par.params, "rlat_ts").f : HALFPI;
+ setup(par, proj_parm);
+ }
+
+ // Universal Polar Stereographic
+ template <typename Parameters>
+ void setup_ups(Parameters& par, par_stere& proj_parm)
+ {
+ /* International Ellipsoid */
+ par.phi0 = pj_param(par.params, "bsouth").i ? - HALFPI: HALFPI;
+ if (!par.es) throw proj_exception(-34);
+ par.k0 = .994;
+ par.x0 = 2000000.;
+ par.y0 = 2000000.;
+ proj_parm.phits = HALFPI;
+ par.lam0 = 0.;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::stere
+ #endif // doxygen
+
+ /*!
+ \brief Stereographic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ - lat_ts=
+ \par Example
+ \image html ex_stere.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct stere_ellipsoid : public detail::stere::base_stere_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline stere_ellipsoid(const Parameters& par) : detail::stere::base_stere_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::stere::setup_stere(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Universal Polar Stereographic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ - south
+ \par Example
+ \image html ex_ups.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct ups_ellipsoid : public detail::stere::base_stere_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline ups_ellipsoid(const Parameters& par) : detail::stere::base_stere_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::stere::setup_ups(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Stereographic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ - lat_ts=
+ \par Example
+ \image html ex_stere.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct stere_spheroid : public detail::stere::base_stere_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline stere_spheroid(const Parameters& par) : detail::stere::base_stere_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::stere::setup_stere(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class stere_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<stere_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<stere_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class ups_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<ups_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void stere_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("stere", new stere_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("ups", new ups_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_STERE_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/sterea.hpp b/src/boost/geometry/extensions/gis/projections/proj/sterea.hpp
new file mode 100644
index 0000000..1d5454d
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/sterea.hpp
@@ -0,0 +1,381 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_gauss.hpp>
+
+#include <boost/geometry/extensions/gis/projections/epsg_traits.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace sterea{
+ static const double DEL_TOL = 1.e-14;
+ static const int MAX_ITER = 10;
+
+ struct par_sterea
+ {
+ double phic0;
+ double cosc0, sinc0;
+ double R2;
+ gauss::GAUSS en;
+ };
+
+
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_sterea_ellipsoid : public base_t_fi<base_sterea_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_sterea m_proj_parm;
+
+ inline base_sterea_ellipsoid(const Parameters& par)
+ : base_t_fi<base_sterea_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double cosc, sinc, cosl, k;
+
+ detail::gauss::gauss(m_proj_parm.en, lp_lon, lp_lat);
+ sinc = sin(lp_lat);
+ cosc = cos(lp_lat);
+ cosl = cos(lp_lon);
+ k = this->m_par.k0 * this->m_proj_parm.R2 / (1. + this->m_proj_parm.sinc0 * sinc + this->m_proj_parm.cosc0 * cosc * cosl);
+ xy_x = k * cosc * sin(lp_lon);
+ xy_y = k * (this->m_proj_parm.cosc0 * sinc - this->m_proj_parm.sinc0 * cosc * cosl);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double rho, c, sinc, cosc;
+
+ xy_x /= this->m_par.k0;
+ xy_y /= this->m_par.k0;
+ if((rho = boost::math::hypot(xy_x, xy_y))) {
+ c = 2. * atan2(rho, this->m_proj_parm.R2);
+ sinc = sin(c);
+ cosc = cos(c);
+ lp_lat = asin(cosc * this->m_proj_parm.sinc0 + xy_y * sinc * this->m_proj_parm.cosc0 / rho);
+ lp_lon = atan2(xy_x * sinc, rho * this->m_proj_parm.cosc0 * cosc -
+ xy_y * this->m_proj_parm.sinc0 * sinc);
+ } else {
+ lp_lat = this->m_proj_parm.phic0;
+ lp_lon = 0.;
+ }
+ detail::gauss::inv_gauss(m_proj_parm.en, lp_lon, lp_lat);
+ }
+ };
+
+ // Oblique Stereographic Alternative
+ template <typename Parameters>
+ void setup_sterea(Parameters& par, par_sterea& proj_parm)
+ {
+ double R;
+ proj_parm.en = detail::gauss::gauss_ini(par.e, par.phi0, proj_parm.phic0, R);
+ proj_parm.sinc0 = sin(proj_parm.phic0);
+ proj_parm.cosc0 = cos(proj_parm.phic0);
+ proj_parm.R2 = 2. * R;
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ }
+
+ }} // namespace detail::sterea
+ #endif // doxygen
+
+ /*!
+ \brief Oblique Stereographic Alternative projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Azimuthal
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_sterea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct sterea_ellipsoid : public detail::sterea::base_sterea_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline sterea_ellipsoid(const Parameters& par) : detail::sterea::base_sterea_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sterea::setup_sterea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class sterea_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<sterea_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void sterea_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("sterea", new sterea_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ // Create EPSG specializations
+ // (Proof of Concept, only for some)
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2036, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=46.5 +lon_0=-66.5 +k=0.999912 +x_0=2500000 +y_0=7500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2171, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=50.625 +lon_0=21.08333333333333 +k=0.9998 +x_0=4637000 +y_0=5647000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2172, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=53.00194444444445 +lon_0=21.50277777777778 +k=0.9998 +x_0=4603000 +y_0=5806000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2173, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=53.58333333333334 +lon_0=17.00833333333333 +k=0.9998 +x_0=3501000 +y_0=5999000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2174, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=51.67083333333333 +lon_0=16.67222222222222 +k=0.9998 +x_0=3703000 +y_0=5627000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2200, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=46.5 +lon_0=-66.5 +k=0.999912 +x_0=300000 +y_0=800000 +a=6378135 +b=6356750.304921594 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2290, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=47.25 +lon_0=-63 +k=0.999912 +x_0=700000 +y_0=400000 +a=6378135 +b=6356750.304921594 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2291, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=47.25 +lon_0=-63 +k=0.999912 +x_0=400000 +y_0=800000 +a=6378135 +b=6356750.304921594 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2292, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=47.25 +lon_0=-63 +k=0.999912 +x_0=400000 +y_0=800000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2953, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=46.5 +lon_0=-66.5 +k=0.999912 +x_0=2500000 +y_0=7500000 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2954, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=47.25 +lon_0=-63 +k=0.999912 +x_0=400000 +y_0=800000 +ellps=GRS80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3120, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=50.625 +lon_0=21.08333333333333 +k=0.9998 +x_0=4637000 +y_0=5467000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<3328, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=52.16666666666666 +lon_0=19.16666666666667 +k=0.999714 +x_0=500000 +y_0=500000 +ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<22780, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=34.2 +lon_0=39.15 +k=0.9995341 +x_0=0 +y_0=0 +a=6378249.2 +b=6356515 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<28991, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=0 +y_0=0 +ellps=bessel +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<28992, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<31600, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=45.9 +lon_0=25.39246588888889 +k=0.9996667 +x_0=500000 +y_0=500000 +ellps=intl +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<31700, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef sterea_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=sterea +lat_0=46 +lon_0=25 +k=0.99975 +x_0=500000 +y_0=500000 +ellps=krass +units=m";
+ }
+ };
+
+
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/sts.hpp b/src/boost/geometry/extensions/gis/projections/proj/sts.hpp
new file mode 100644
index 0000000..6a3cf04
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/sts.hpp
@@ -0,0 +1,294 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_STS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_STS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace sts{
+
+ struct par_sts
+ {
+ double C_x, C_y, C_p;
+ int tan_mode;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_sts_spheroid : public base_t_fi<base_sts_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_sts m_proj_parm;
+
+ inline base_sts_spheroid(const Parameters& par)
+ : base_t_fi<base_sts_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double c;
+
+ xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat);
+ xy_y = this->m_proj_parm.C_y;
+ lp_lat *= this->m_proj_parm.C_p;
+ c = cos(lp_lat);
+ if (this->m_proj_parm.tan_mode) {
+ xy_x *= c * c;
+ xy_y *= tan(lp_lat);
+ } else {
+ xy_x /= c;
+ xy_y *= sin(lp_lat);
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double c;
+
+ xy_y /= this->m_proj_parm.C_y;
+ c = cos(lp_lat = this->m_proj_parm.tan_mode ? atan(xy_y) : aasin(xy_y));
+ lp_lat /= this->m_proj_parm.C_p;
+ lp_lon = xy_x / (this->m_proj_parm.C_x * cos(lp_lat));
+ if (this->m_proj_parm.tan_mode)
+ lp_lon /= c * c;
+ else
+ lp_lon *= c;
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_sts& proj_parm, double p, double q, int mode)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ proj_parm.C_x = q / p;
+ proj_parm.C_y = p;
+ proj_parm.C_p = 1/ q;
+ proj_parm.tan_mode = mode;
+ }
+
+
+ // Kavraisky V
+ template <typename Parameters>
+ void setup_kav5(Parameters& par, par_sts& proj_parm)
+ {
+ setup(par, proj_parm, 1.50488, 1.35439, 0);
+ }
+
+ // Quartic Authalic
+ template <typename Parameters>
+ void setup_qua_aut(Parameters& par, par_sts& proj_parm)
+ {
+ setup(par, proj_parm, 2., 2., 0);
+ }
+
+ // McBryde-Thomas Flat-Polar Sine (No. 1)
+ template <typename Parameters>
+ void setup_mbt_s(Parameters& par, par_sts& proj_parm)
+ {
+ setup(par, proj_parm, 1.48875, 1.36509, 0);
+ }
+
+ // Foucaut
+ template <typename Parameters>
+ void setup_fouc(Parameters& par, par_sts& proj_parm)
+ {
+ setup(par, proj_parm, 2., 2., 1);
+ }
+
+ }} // namespace detail::sts
+ #endif // doxygen
+
+ /*!
+ \brief Kavraisky V projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_kav5.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct kav5_spheroid : public detail::sts::base_sts_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline kav5_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sts::setup_kav5(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Quartic Authalic projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_qua_aut.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct qua_aut_spheroid : public detail::sts::base_sts_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline qua_aut_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sts::setup_qua_aut(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief McBryde-Thomas Flat-Polar Sine (No. 1) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_mbt_s.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct mbt_s_spheroid : public detail::sts::base_sts_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline mbt_s_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sts::setup_mbt_s(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Foucaut projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_fouc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct fouc_spheroid : public detail::sts::base_sts_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline fouc_spheroid(const Parameters& par) : detail::sts::base_sts_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::sts::setup_fouc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class kav5_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<kav5_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class qua_aut_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<qua_aut_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class mbt_s_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<mbt_s_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class fouc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<fouc_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void sts_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("kav5", new kav5_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("qua_aut", new qua_aut_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("mbt_s", new mbt_s_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("fouc", new fouc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_STS_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/tcc.hpp b/src/boost/geometry/extensions/gis/projections/proj/tcc.hpp
new file mode 100644
index 0000000..5fa22d4
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/tcc.hpp
@@ -0,0 +1,142 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_TCC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_TCC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace tcc{
+ static const double EPS10 = 1.e-10;
+
+ struct par_tcc
+ {
+ double ap;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_tcc_spheroid : public base_t_f<base_tcc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_tcc m_proj_parm;
+
+ inline base_tcc_spheroid(const Parameters& par)
+ : base_t_f<base_tcc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double b, bt;
+
+ b = cos(lp_lat) * sin(lp_lon);
+ if ((bt = 1. - b * b) < EPS10) throw proj_exception();;
+ xy_x = b / sqrt(bt);
+ xy_y = atan2(tan(lp_lat) , cos(lp_lon));
+ }
+ };
+
+ // Transverse Central Cylindrical
+ template <typename Parameters>
+ void setup_tcc(Parameters& par, par_tcc& proj_parm)
+ {
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::tcc
+ #endif // doxygen
+
+ /*!
+ \brief Transverse Central Cylindrical projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_tcc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct tcc_spheroid : public detail::tcc::base_tcc_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline tcc_spheroid(const Parameters& par) : detail::tcc::base_tcc_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::tcc::setup_tcc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class tcc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<tcc_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void tcc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("tcc", new tcc_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_TCC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/tcea.hpp b/src/boost/geometry/extensions/gis/projections/proj/tcea.hpp
new file mode 100644
index 0000000..9b6d2f9
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/tcea.hpp
@@ -0,0 +1,149 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace tcea{
+
+ struct par_tcea
+ {
+ double rk0;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_tcea_spheroid : public base_t_fi<base_tcea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_tcea m_proj_parm;
+
+ inline base_tcea_spheroid(const Parameters& par)
+ : base_t_fi<base_tcea_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = this->m_proj_parm.rk0 * cos(lp_lat) * sin(lp_lon);
+ xy_y = this->m_par.k0 * (atan2(tan(lp_lat), cos(lp_lon)) - this->m_par.phi0);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double t;
+
+ xy_y = xy_y * this->m_proj_parm.rk0 + this->m_par.phi0;
+ xy_x *= this->m_par.k0;
+ t = sqrt(1. - xy_x * xy_x);
+ lp_lat = asin(t * sin(xy_y));
+ lp_lon = atan2(xy_x, t * cos(xy_y));
+ }
+ };
+
+ // Transverse Cylindrical Equal Area
+ template <typename Parameters>
+ void setup_tcea(Parameters& par, par_tcea& proj_parm)
+ {
+ proj_parm.rk0 = 1 / par.k0;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::tcea
+ #endif // doxygen
+
+ /*!
+ \brief Transverse Cylindrical Equal Area projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ \par Example
+ \image html ex_tcea.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct tcea_spheroid : public detail::tcea::base_tcea_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline tcea_spheroid(const Parameters& par) : detail::tcea::base_tcea_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::tcea::setup_tcea(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class tcea_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<tcea_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void tcea_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("tcea", new tcea_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_TCEA_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/tmerc.hpp b/src/boost/geometry/extensions/gis/projections/proj/tmerc.hpp
new file mode 100644
index 0000000..b419386
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/tmerc.hpp
@@ -0,0 +1,458 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/function_overloads.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/pj_mlfn.hpp>
+
+#include <boost/geometry/extensions/gis/projections/epsg_traits.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace tmerc{
+ static const double EPS10 = 1.e-10;
+ static const double FC1 = 1.;
+ static const double FC2 = .5;
+ static const double FC3 = .16666666666666666666;
+ static const double FC4 = .08333333333333333333;
+ static const double FC5 = .05;
+ static const double FC6 = .03333333333333333333;
+ static const double FC7 = .02380952380952380952;
+ static const double FC8 = .01785714285714285714;
+
+ struct par_tmerc
+ {
+ double esp;
+ double ml0;
+ double en[EN_SIZE];
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_tmerc_ellipsoid : public base_t_fi<base_tmerc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_tmerc m_proj_parm;
+
+ inline base_tmerc_ellipsoid(const Parameters& par)
+ : base_t_fi<base_tmerc_ellipsoid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double al, als, n, cosphi, sinphi, t;
+
+ /*
+ * Fail if our longitude is more than 90 degrees from the
+ * central meridian since the results are essentially garbage.
+ * Is error -20 really an appropriate return value?
+ *
+ * http://trac.osgeo.org/proj/ticket/5
+ */
+ if( lp_lon < -HALFPI || lp_lon > HALFPI )
+ {
+ xy_x = HUGE_VAL;
+ xy_y = HUGE_VAL;
+ throw proj_exception( -14);
+ return;
+ }
+
+ sinphi = sin(lp_lat); cosphi = cos(lp_lat);
+ t = fabs(cosphi) > 1e-10 ? sinphi/cosphi : 0.;
+ t *= t;
+ al = cosphi * lp_lon;
+ als = al * al;
+ al /= sqrt(1. - this->m_par.es * sinphi * sinphi);
+ n = this->m_proj_parm.esp * cosphi * cosphi;
+ xy_x = this->m_par.k0 * al * (FC1 +
+ FC3 * als * (1. - t + n +
+ FC5 * als * (5. + t * (t - 18.) + n * (14. - 58. * t)
+ + FC7 * als * (61. + t * ( t * (179. - t) - 479. ) )
+ )));
+ xy_y = this->m_par.k0 * (pj_mlfn(lp_lat, sinphi, cosphi, this->m_proj_parm.en) - this->m_proj_parm.ml0 +
+ sinphi * al * lp_lon * FC2 * ( 1. +
+ FC4 * als * (5. - t + n * (9. + 4. * n) +
+ FC6 * als * (61. + t * (t - 58.) + n * (270. - 330 * t)
+ + FC8 * als * (1385. + t * ( t * (543. - t) - 3111.) )
+ ))));
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double n, con, cosphi, d, ds, sinphi, t;
+
+ lp_lat = pj_inv_mlfn(this->m_proj_parm.ml0 + xy_y / this->m_par.k0, this->m_par.es, this->m_proj_parm.en);
+ if (fabs(lp_lat) >= HALFPI) {
+ lp_lat = xy_y < 0. ? -HALFPI : HALFPI;
+ lp_lon = 0.;
+ } else {
+ sinphi = sin(lp_lat);
+ cosphi = cos(lp_lat);
+ t = fabs(cosphi) > 1e-10 ? sinphi/cosphi : 0.;
+ n = this->m_proj_parm.esp * cosphi * cosphi;
+ d = xy_x * sqrt(con = 1. - this->m_par.es * sinphi * sinphi) / this->m_par.k0;
+ con *= t;
+ t *= t;
+ ds = d * d;
+ lp_lat -= (con * ds / (1.-this->m_par.es)) * FC2 * (1. -
+ ds * FC4 * (5. + t * (3. - 9. * n) + n * (1. - 4 * n) -
+ ds * FC6 * (61. + t * (90. - 252. * n +
+ 45. * t) + 46. * n
+ - ds * FC8 * (1385. + t * (3633. + t * (4095. + 1574. * t)) )
+ )));
+ lp_lon = d*(FC1 -
+ ds*FC3*( 1. + 2.*t + n -
+ ds*FC5*(5. + t*(28. + 24.*t + 8.*n) + 6.*n
+ - ds * FC7 * (61. + t * (662. + t * (1320. + 720. * t)) )
+ ))) / cosphi;
+ }
+ }
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_tmerc_spheroid : public base_t_fi<base_tmerc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_tmerc m_proj_parm;
+
+ inline base_tmerc_spheroid(const Parameters& par)
+ : base_t_fi<base_tmerc_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double b, cosphi;
+
+ /*
+ * Fail if our longitude is more than 90 degrees from the
+ * central meridian since the results are essentially garbage.
+ * Is error -20 really an appropriate return value?
+ *
+ * http://trac.osgeo.org/proj/ticket/5
+ */
+ if( lp_lon < -HALFPI || lp_lon > HALFPI )
+ {
+ xy_x = HUGE_VAL;
+ xy_y = HUGE_VAL;
+ throw proj_exception( -14);
+ return;
+ }
+
+ b = (cosphi = cos(lp_lat)) * sin(lp_lon);
+ if (fabs(fabs(b) - 1.) <= EPS10) throw proj_exception();;
+ xy_x = this->m_proj_parm.ml0 * log((1. + b) / (1. - b));
+ if ((b = fabs( xy_y = cosphi * cos(lp_lon) / sqrt(1. - b * b) )) >= 1.) {
+ if ((b - 1.) > EPS10) throw proj_exception();
+ else xy_y = 0.;
+ } else
+ xy_y = acos(xy_y);
+ if (lp_lat < 0.) xy_y = -xy_y;
+ xy_y = this->m_proj_parm.esp * (xy_y - this->m_par.phi0);
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double h, g;
+
+ h = exp(xy_x / this->m_proj_parm.esp);
+ g = .5 * (h - 1. / h);
+ h = cos(this->m_par.phi0 + xy_y / this->m_proj_parm.esp);
+ lp_lat = asin(sqrt((1. - h * h) / (1. + g * g)));
+ if (xy_y < 0.) lp_lat = -lp_lat;
+ lp_lon = (g || h) ? atan2(g, h) : 0.;
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_tmerc& proj_parm) /* general initialization */
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ if (par.es) {
+ pj_enfn(par.es, proj_parm.en);
+
+ proj_parm.ml0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en);
+ proj_parm.esp = par.es / (1. - par.es);
+ // par.inv = e_inverse;
+ // par.fwd = e_forward;
+ } else {
+ proj_parm.esp = par.k0;
+ proj_parm.ml0 = .5 * proj_parm.esp;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+ }
+
+
+ // Transverse Mercator
+ template <typename Parameters>
+ void setup_tmerc(Parameters& par, par_tmerc& proj_parm)
+ {
+ setup(par, proj_parm);
+ }
+
+ // Universal Transverse Mercator (UTM)
+ template <typename Parameters>
+ void setup_utm(Parameters& par, par_tmerc& proj_parm)
+ {
+ int zone;
+ if (!par.es) throw proj_exception(-34);
+ par.y0 = pj_param(par.params, "bsouth").i ? 10000000. : 0.;
+ par.x0 = 500000.;
+ if (pj_param(par.params, "tzone").i) /* zone input ? */
+ if ((zone = pj_param(par.params, "izone").i) > 0 && zone <= 60)
+ --zone;
+ else
+ throw proj_exception(-35);
+ else /* nearest central meridian input */
+ if ((zone = int_floor((adjlon(par.lam0) + PI) * 30. / PI)) < 0)
+ zone = 0;
+ else if (zone >= 60)
+ zone = 59;
+ par.lam0 = (zone + .5) * PI / 30. - PI;
+ par.k0 = 0.9996;
+ par.phi0 = 0.;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::tmerc
+ #endif // doxygen
+
+ /*!
+ \brief Transverse Mercator projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_tmerc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct tmerc_ellipsoid : public detail::tmerc::base_tmerc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline tmerc_ellipsoid(const Parameters& par) : detail::tmerc::base_tmerc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::tmerc::setup_tmerc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Universal Transverse Mercator (UTM) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - zone= south
+ \par Example
+ \image html ex_utm.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct utm_ellipsoid : public detail::tmerc::base_tmerc_ellipsoid<Geographic, Cartesian, Parameters>
+ {
+ inline utm_ellipsoid(const Parameters& par) : detail::tmerc::base_tmerc_ellipsoid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::tmerc::setup_utm(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Transverse Mercator projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Cylindrical
+ - Spheroid
+ - Ellipsoid
+ \par Example
+ \image html ex_tmerc.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct tmerc_spheroid : public detail::tmerc::base_tmerc_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline tmerc_spheroid(const Parameters& par) : detail::tmerc::base_tmerc_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::tmerc::setup_tmerc(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class tmerc_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ if (par.es)
+ return new base_v_fi<tmerc_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ else
+ return new base_v_fi<tmerc_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class utm_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<utm_ellipsoid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void tmerc_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("tmerc", new tmerc_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("utm", new utm_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ // Create EPSG specializations
+ // (Proof of Concept, only for some)
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2000, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef tmerc_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2001, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef tmerc_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2002, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef tmerc_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +towgs84=725,685,536,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2003, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef tmerc_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +towgs84=72,213.7,93,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<2039, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef tmerc_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=tmerc +lat_0=31.73439361111111 +lon_0=35.20451694444445 +k=1.0000067 +x_0=219529.584 +y_0=626907.39 +ellps=GRS80 +towgs84=-48,55,52,0,0,0,0 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<29118, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef utm_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=utm +zone=18 +ellps=GRS67 +units=m";
+ }
+ };
+
+
+ template<typename LatLongRadian, typename Cartesian, typename Parameters>
+ struct epsg_traits<29119, LatLongRadian, Cartesian, Parameters>
+ {
+ typedef utm_ellipsoid<LatLongRadian, Cartesian, Parameters> type;
+ static inline std::string par()
+ {
+ return "+proj=utm +zone=19 +ellps=GRS67 +units=m";
+ }
+ };
+
+
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_TMERC_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/tpeqd.hpp b/src/boost/geometry/extensions/gis/projections/proj/tpeqd.hpp
new file mode 100644
index 0000000..aa26534
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/tpeqd.hpp
@@ -0,0 +1,198 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace tpeqd{
+
+ struct par_tpeqd
+ {
+ double cp1, sp1, cp2, sp2, ccs, cs, sc, r2z0, z02, dlam2;
+ double hz0, thz0, rhshz0, ca, sa, lp, lamc;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_tpeqd_spheroid : public base_t_fi<base_tpeqd_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_tpeqd m_proj_parm;
+
+ inline base_tpeqd_spheroid(const Parameters& par)
+ : base_t_fi<base_tpeqd_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double t, z1, z2, dl1, dl2, sp, cp;
+
+ sp = sin(lp_lat);
+ cp = cos(lp_lat);
+ z1 = aacos(this->m_proj_parm.sp1 * sp + this->m_proj_parm.cp1 * cp * cos(dl1 = lp_lon + this->m_proj_parm.dlam2));
+ z2 = aacos(this->m_proj_parm.sp2 * sp + this->m_proj_parm.cp2 * cp * cos(dl2 = lp_lon - this->m_proj_parm.dlam2));
+ z1 *= z1;
+ z2 *= z2;
+ xy_x = this->m_proj_parm.r2z0 * (t = z1 - z2);
+ t = this->m_proj_parm.z02 - t;
+ xy_y = this->m_proj_parm.r2z0 * asqrt(4. * this->m_proj_parm.z02 * z2 - t * t);
+ if ((this->m_proj_parm.ccs * sp - cp * (this->m_proj_parm.cs * sin(dl1) - this->m_proj_parm.sc * sin(dl2))) < 0.)
+ xy_y = -xy_y;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double cz1, cz2, s, d, cp, sp;
+
+ cz1 = cos(boost::math::hypot(xy_y, xy_x + this->m_proj_parm.hz0));
+ cz2 = cos(boost::math::hypot(xy_y, xy_x - this->m_proj_parm.hz0));
+ s = cz1 + cz2;
+ d = cz1 - cz2;
+ lp_lon = - atan2(d, (s * this->m_proj_parm.thz0));
+ lp_lat = aacos(boost::math::hypot(this->m_proj_parm.thz0 * s, d) * this->m_proj_parm.rhshz0);
+ if ( xy_y < 0. )
+ lp_lat = - lp_lat;
+ /* lam--phi now in system relative to P1--P2 base equator */
+ sp = sin(lp_lat);
+ cp = cos(lp_lat);
+ lp_lat = aasin(this->m_proj_parm.sa * sp + this->m_proj_parm.ca * cp * (s = cos(lp_lon -= this->m_proj_parm.lp)));
+ lp_lon = atan2(cp * sin(lp_lon), this->m_proj_parm.sa * cp * s - this->m_proj_parm.ca * sp) + this->m_proj_parm.lamc;
+ }
+ };
+
+ // Two Point Equidistant
+ template <typename Parameters>
+ void setup_tpeqd(Parameters& par, par_tpeqd& proj_parm)
+ {
+ double lam_1, lam_2, phi_1, phi_2, A12, pp;
+ /* get control point locations */
+ phi_1 = pj_param(par.params, "rlat_1").f;
+ lam_1 = pj_param(par.params, "rlon_1").f;
+ phi_2 = pj_param(par.params, "rlat_2").f;
+ lam_2 = pj_param(par.params, "rlon_2").f;
+ if (phi_1 == phi_2 && lam_1 == lam_2) throw proj_exception(-25);
+ par.lam0 = adjlon(0.5 * (lam_1 + lam_2));
+ proj_parm.dlam2 = adjlon(lam_2 - lam_1);
+ proj_parm.cp1 = cos(phi_1);
+ proj_parm.cp2 = cos(phi_2);
+ proj_parm.sp1 = sin(phi_1);
+ proj_parm.sp2 = sin(phi_2);
+ proj_parm.cs = proj_parm.cp1 * proj_parm.sp2;
+ proj_parm.sc = proj_parm.sp1 * proj_parm.cp2;
+ proj_parm.ccs = proj_parm.cp1 * proj_parm.cp2 * sin(proj_parm.dlam2);
+ proj_parm.z02 = aacos(proj_parm.sp1 * proj_parm.sp2 + proj_parm.cp1 * proj_parm.cp2 * cos(proj_parm.dlam2));
+ proj_parm.hz0 = .5 * proj_parm.z02;
+ A12 = atan2(proj_parm.cp2 * sin(proj_parm.dlam2),
+ proj_parm.cp1 * proj_parm.sp2 - proj_parm.sp1 * proj_parm.cp2 * cos(proj_parm.dlam2));
+ proj_parm.ca = cos(pp = aasin(proj_parm.cp1 * sin(A12)));
+ proj_parm.sa = sin(pp);
+ proj_parm.lp = adjlon(atan2(proj_parm.cp1 * cos(A12), proj_parm.sp1) - proj_parm.hz0);
+ proj_parm.dlam2 *= .5;
+ proj_parm.lamc = HALFPI - atan2(sin(A12) * proj_parm.sp1, cos(A12)) - proj_parm.dlam2;
+ proj_parm.thz0 = tan(proj_parm.hz0);
+ proj_parm.rhshz0 = .5 / sin(proj_parm.hz0);
+ proj_parm.r2z0 = 0.5 / proj_parm.z02;
+ proj_parm.z02 *= proj_parm.z02;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::tpeqd
+ #endif // doxygen
+
+ /*!
+ \brief Two Point Equidistant projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - lat_1= lon_1= lat_2= lon_2=
+ \par Example
+ \image html ex_tpeqd.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct tpeqd_spheroid : public detail::tpeqd::base_tpeqd_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline tpeqd_spheroid(const Parameters& par) : detail::tpeqd::base_tpeqd_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::tpeqd::setup_tpeqd(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class tpeqd_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<tpeqd_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void tpeqd_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("tpeqd", new tpeqd_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_TPEQD_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/urm5.hpp b/src/boost/geometry/extensions/gis/projections/proj/urm5.hpp
new file mode 100644
index 0000000..157dd10
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/urm5.hpp
@@ -0,0 +1,149 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_URM5_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_URM5_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace urm5{
+
+ struct par_urm5
+ {
+ double m, rmn, q3, n;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_urm5_spheroid : public base_t_f<base_urm5_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_urm5 m_proj_parm;
+
+ inline base_urm5_spheroid(const Parameters& par)
+ : base_t_f<base_urm5_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double t;
+
+ t = lp_lat = aasin(this->m_proj_parm.n * sin(lp_lat));
+ xy_x = this->m_proj_parm.m * lp_lon * cos(lp_lat);
+ t *= t;
+ xy_y = lp_lat * (1. + t * this->m_proj_parm.q3) * this->m_proj_parm.rmn;
+ }
+ };
+
+ // Urmaev V
+ template <typename Parameters>
+ void setup_urm5(Parameters& par, par_urm5& proj_parm)
+ {
+ double alpha, t;
+ proj_parm.n = pj_param(par.params, "dn").f;
+ proj_parm.q3 = pj_param(par.params, "dq").f / 3.;
+ alpha = pj_param(par.params, "ralpha").f;
+ t = proj_parm.n * sin(alpha);
+ proj_parm.m = cos(alpha) / sqrt(1. - t * t);
+ proj_parm.rmn = 1. / (proj_parm.m * proj_parm.n);
+ par.es = 0.;
+ // par.inv = 0;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::urm5
+ #endif // doxygen
+
+ /*!
+ \brief Urmaev V projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - n= q= alphi=
+ \par Example
+ \image html ex_urm5.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct urm5_spheroid : public detail::urm5::base_urm5_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline urm5_spheroid(const Parameters& par) : detail::urm5::base_urm5_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::urm5::setup_urm5(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class urm5_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<urm5_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void urm5_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("urm5", new urm5_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_URM5_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/urmfps.hpp b/src/boost/geometry/extensions/gis/projections/proj/urmfps.hpp
new file mode 100644
index 0000000..e2375a6
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/urmfps.hpp
@@ -0,0 +1,205 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/concept_check.hpp>
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace urmfps{
+ static const double C_x = 0.8773826753;
+ static const double Cy = 1.139753528477;
+
+ struct par_urmfps
+ {
+ double n, C_y;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_urmfps_spheroid : public base_t_fi<base_urmfps_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_urmfps m_proj_parm;
+
+ inline base_urmfps_spheroid(const Parameters& par)
+ : base_t_fi<base_urmfps_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat = aasin(this->m_proj_parm.n * sin(lp_lat));
+ xy_x = C_x * lp_lon * cos(lp_lat);
+ xy_y = this->m_proj_parm.C_y * lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ xy_y /= this->m_proj_parm.C_y;
+ lp_lat = aasin(sin(xy_y) / this->m_proj_parm.n);
+ lp_lon = xy_x / (C_x * cos(xy_y));
+ }
+ };
+
+ template <typename Parameters>
+ void setup(Parameters& par, par_urmfps& proj_parm)
+ {
+ boost::ignore_unused_variable_warning(par);
+ boost::ignore_unused_variable_warning(proj_parm);
+ proj_parm.C_y = Cy / proj_parm.n;
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+
+ // Urmaev Flat-Polar Sinusoidal
+ template <typename Parameters>
+ void setup_urmfps(Parameters& par, par_urmfps& proj_parm)
+ {
+ if (pj_param(par.params, "tn").i) {
+ proj_parm.n = pj_param(par.params, "dn").f;
+ if (proj_parm.n <= 0. || proj_parm.n > 1.)
+ throw proj_exception(-40);
+ } else
+ throw proj_exception(-40);
+ setup(par, proj_parm);
+ }
+
+ // Wagner I (Kavraisky VI)
+ template <typename Parameters>
+ void setup_wag1(Parameters& par, par_urmfps& proj_parm)
+ {
+ proj_parm.n = 0.8660254037844386467637231707;
+ setup(par, proj_parm);
+ }
+
+ }} // namespace detail::urmfps
+ #endif // doxygen
+
+ /*!
+ \brief Urmaev Flat-Polar Sinusoidal projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - n=
+ \par Example
+ \image html ex_urmfps.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct urmfps_spheroid : public detail::urmfps::base_urmfps_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline urmfps_spheroid(const Parameters& par) : detail::urmfps::base_urmfps_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::urmfps::setup_urmfps(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief Wagner I (Kavraisky VI) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_wag1.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wag1_spheroid : public detail::urmfps::base_urmfps_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wag1_spheroid(const Parameters& par) : detail::urmfps::base_urmfps_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::urmfps::setup_wag1(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class urmfps_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<urmfps_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wag1_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wag1_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void urmfps_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("urmfps", new urmfps_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("wag1", new wag1_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_URMFPS_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/vandg.hpp b/src/boost/geometry/extensions/gis/projections/proj/vandg.hpp
new file mode 100644
index 0000000..12225d5
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/vandg.hpp
@@ -0,0 +1,201 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace vandg{
+ static const double TOL = 1.e-10;
+ static const double THIRD = .33333333333333333333;
+ static const double TWO_THRD = .66666666666666666666;
+ static const double C2_27 = .07407407407407407407;
+ static const double PI4_3 = 4.18879020478639098458;
+ static const double PISQ = 9.86960440108935861869;
+ static const double TPISQ = 19.73920880217871723738;
+ static const double HPISQ = 4.93480220054467930934;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_vandg_spheroid : public base_t_fi<base_vandg_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_vandg_spheroid(const Parameters& par)
+ : base_t_fi<base_vandg_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double al, al2, g, g2, p2;
+
+ p2 = fabs(lp_lat / HALFPI);
+ if ((p2 - TOL) > 1.) throw proj_exception();;
+ if (p2 > 1.)
+ p2 = 1.;
+ if (fabs(lp_lat) <= TOL) {
+ xy_x = lp_lon;
+ xy_y = 0.;
+ } else if (fabs(lp_lon) <= TOL || fabs(p2 - 1.) < TOL) {
+ xy_x = 0.;
+ xy_y = PI * tan(.5 * asin(p2));
+ if (lp_lat < 0.) xy_y = -xy_y;
+ } else {
+ al = .5 * fabs(PI / lp_lon - lp_lon / PI);
+ al2 = al * al;
+ g = sqrt(1. - p2 * p2);
+ g = g / (p2 + g - 1.);
+ g2 = g * g;
+ p2 = g * (2. / p2 - 1.);
+ p2 = p2 * p2;
+ xy_x = g - p2; g = p2 + al2;
+ xy_x = PI * (al * xy_x + sqrt(al2 * xy_x * xy_x - g * (g2 - p2))) / g;
+ if (lp_lon < 0.) xy_x = -xy_x;
+ xy_y = fabs(xy_x / PI);
+ xy_y = 1. - xy_y * (xy_y + 2. * al);
+ if (xy_y < -TOL) throw proj_exception();;
+ if (xy_y < 0.) xy_y = 0.;
+ else xy_y = sqrt(xy_y) * (lp_lat < 0. ? -PI : PI);
+ }
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ double t, c0, c1, c2, c3, al, r2, r, m, d, ay, x2, y2;
+
+ x2 = xy_x * xy_x;
+ if ((ay = fabs(xy_y)) < TOL) {
+ lp_lat = 0.;
+ t = x2 * x2 + TPISQ * (x2 + HPISQ);
+ lp_lon = fabs(xy_x) <= TOL ? 0. :
+ .5 * (x2 - PISQ + sqrt(t)) / xy_x;
+ return;
+ }
+ y2 = xy_y * xy_y;
+ r = x2 + y2; r2 = r * r;
+ c1 = - PI * ay * (r + PISQ);
+ c3 = r2 + TWOPI * (ay * r + PI * (y2 + PI * (ay + HALFPI)));
+ c2 = c1 + PISQ * (r - 3. * y2);
+ c0 = PI * ay;
+ c2 /= c3;
+ al = c1 / c3 - THIRD * c2 * c2;
+ m = 2. * sqrt(-THIRD * al);
+ d = C2_27 * c2 * c2 * c2 + (c0 * c0 - THIRD * c2 * c1) / c3;
+ if (((t = fabs(d = 3. * d / (al * m))) - TOL) <= 1.) {
+ d = t > 1. ? (d > 0. ? 0. : PI) : acos(d);
+ lp_lat = PI * (m * cos(d * THIRD + PI4_3) - THIRD * c2);
+ if (xy_y < 0.) lp_lat = -lp_lat;
+ t = r2 + TPISQ * (x2 - y2 + HPISQ);
+ lp_lon = fabs(xy_x) <= TOL ? 0. :
+ .5 * (r - PISQ + (t <= 0. ? 0. : sqrt(t))) / xy_x;
+ } else
+ throw proj_exception();;
+ }
+ };
+
+ // van der Grinten (I)
+ template <typename Parameters>
+ void setup_vandg(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::vandg
+ #endif // doxygen
+
+ /*!
+ \brief van der Grinten (I) projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ \par Example
+ \image html ex_vandg.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct vandg_spheroid : public detail::vandg::base_vandg_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline vandg_spheroid(const Parameters& par) : detail::vandg::base_vandg_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::vandg::setup_vandg(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class vandg_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<vandg_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void vandg_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("vandg", new vandg_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/vandg2.hpp b/src/boost/geometry/extensions/gis/projections/proj/vandg2.hpp
new file mode 100644
index 0000000..b5ca977
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/vandg2.hpp
@@ -0,0 +1,205 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace vandg2{
+ static const double TOL = 1e-10;
+ static const double TWORPI = 0.63661977236758134308;
+
+ struct par_vandg2
+ {
+ int vdg3;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_vandg2_spheroid : public base_t_f<base_vandg2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_vandg2 m_proj_parm;
+
+ inline base_vandg2_spheroid(const Parameters& par)
+ : base_t_f<base_vandg2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double x1, at, bt, ct;
+
+ bt = fabs(TWORPI * lp_lat);
+ if ((ct = 1. - bt * bt) < 0.)
+ ct = 0.;
+ else
+ ct = sqrt(ct);
+ if (fabs(lp_lon) < TOL) {
+ xy_x = 0.;
+ xy_y = PI * (lp_lat < 0. ? -bt : bt) / (1. + ct);
+ } else {
+ at = 0.5 * fabs(PI / lp_lon - lp_lon / PI);
+ if (this->m_proj_parm.vdg3) {
+ x1 = bt / (1. + ct);
+ xy_x = PI * (sqrt(at * at + 1. - x1 * x1) - at);
+ xy_y = PI * x1;
+ } else {
+ x1 = (ct * sqrt(1. + at * at) - at * ct * ct) /
+ (1. + at * at * bt * bt);
+ xy_x = PI * x1;
+ xy_y = PI * sqrt(1. - x1 * (x1 + 2. * at) + TOL);
+ }
+ if ( lp_lon < 0.) xy_x = -xy_x;
+ if ( lp_lat < 0.) xy_y = -xy_y;
+ }
+ }
+ };
+
+ // van der Grinten II
+ template <typename Parameters>
+ void setup_vandg2(Parameters& par, par_vandg2& proj_parm)
+ {
+ proj_parm.vdg3 = 0;
+ // par.inv = 0;
+ // par.fwd = s_forward;
+ }
+
+ // van der Grinten III
+ template <typename Parameters>
+ void setup_vandg3(Parameters& par, par_vandg2& proj_parm)
+ {
+ proj_parm.vdg3 = 1;
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::vandg2
+ #endif // doxygen
+
+ /*!
+ \brief van der Grinten II projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_vandg2.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct vandg2_spheroid : public detail::vandg2::base_vandg2_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline vandg2_spheroid(const Parameters& par) : detail::vandg2::base_vandg2_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::vandg2::setup_vandg2(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ /*!
+ \brief van der Grinten III projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_vandg3.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct vandg3_spheroid : public detail::vandg2::base_vandg2_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline vandg3_spheroid(const Parameters& par) : detail::vandg2::base_vandg2_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::vandg2::setup_vandg3(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class vandg2_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<vandg2_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class vandg3_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<vandg3_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void vandg2_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("vandg2", new vandg2_entry<Geographic, Cartesian, Parameters>);
+ factory.add_to_factory("vandg3", new vandg3_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG2_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/vandg4.hpp b/src/boost/geometry/extensions/gis/projections/proj/vandg4.hpp
new file mode 100644
index 0000000..dab62bf
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/vandg4.hpp
@@ -0,0 +1,163 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace vandg4{
+ static const double TOL = 1e-10;
+ static const double TWORPI = 0.63661977236758134308;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_vandg4_spheroid : public base_t_f<base_vandg4_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_vandg4_spheroid(const Parameters& par)
+ : base_t_f<base_vandg4_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double x1, t, bt, ct, ft, bt2, ct2, dt, dt2;
+
+ if (fabs(lp_lat) < TOL) {
+ xy_x = lp_lon;
+ xy_y = 0.;
+ } else if (fabs(lp_lon) < TOL || fabs(fabs(lp_lat) - HALFPI) < TOL) {
+ xy_x = 0.;
+ xy_y = lp_lat;
+ } else {
+ bt = fabs(TWORPI * lp_lat);
+ bt2 = bt * bt;
+ ct = 0.5 * (bt * (8. - bt * (2. + bt2)) - 5.)
+ / (bt2 * (bt - 1.));
+ ct2 = ct * ct;
+ dt = TWORPI * lp_lon;
+ dt = dt + 1. / dt;
+ dt = sqrt(dt * dt - 4.);
+ if ((fabs(lp_lon) - HALFPI) < 0.) dt = -dt;
+ dt2 = dt * dt;
+ x1 = bt + ct; x1 *= x1;
+ t = bt + 3.*ct;
+ ft = x1 * (bt2 + ct2 * dt2 - 1.) + (1.-bt2) * (
+ bt2 * (t * t + 4. * ct2) +
+ ct2 * (12. * bt * ct + 4. * ct2) );
+ x1 = (dt*(x1 + ct2 - 1.) + 2.*sqrt(ft)) /
+ (4.* x1 + dt2);
+ xy_x = HALFPI * x1;
+ xy_y = HALFPI * sqrt(1. + dt * fabs(x1) - x1 * x1);
+ if (lp_lon < 0.) xy_x = -xy_x;
+ if (lp_lat < 0.) xy_y = -xy_y;
+ }
+ }
+ };
+
+ // van der Grinten IV
+ template <typename Parameters>
+ void setup_vandg4(Parameters& par)
+ {
+ par.es = 0.;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::vandg4
+ #endif // doxygen
+
+ /*!
+ \brief van der Grinten IV projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_vandg4.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct vandg4_spheroid : public detail::vandg4::base_vandg4_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline vandg4_spheroid(const Parameters& par) : detail::vandg4::base_vandg4_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::vandg4::setup_vandg4(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class vandg4_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<vandg4_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void vandg4_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("vandg4", new vandg4_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_VANDG4_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/wag2.hpp b/src/boost/geometry/extensions/gis/projections/proj/wag2.hpp
new file mode 100644
index 0000000..3a1bd51
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/wag2.hpp
@@ -0,0 +1,144 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace wag2{
+ static const double C_x = 0.92483;
+ static const double C_y = 1.38725;
+ static const double C_p1 = 0.88022;
+ static const double C_p2 = 0.88550;
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_wag2_spheroid : public base_t_fi<base_wag2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_wag2_spheroid(const Parameters& par)
+ : base_t_fi<base_wag2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ lp_lat = aasin(C_p1 * sin(C_p2 * lp_lat));
+ xy_x = C_x * lp_lon * cos(lp_lat);
+ xy_y = C_y * lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y / C_y;
+ lp_lon = xy_x / (C_x * cos(lp_lat));
+ lp_lat = aasin(sin(lp_lat) / C_p1) / C_p2;
+ }
+ };
+
+ // Wagner II
+ template <typename Parameters>
+ void setup_wag2(Parameters& par)
+ {
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::wag2
+ #endif // doxygen
+
+ /*!
+ \brief Wagner II projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ \par Example
+ \image html ex_wag2.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wag2_spheroid : public detail::wag2::base_wag2_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wag2_spheroid(const Parameters& par) : detail::wag2::base_wag2_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::wag2::setup_wag2(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wag2_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wag2_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void wag2_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("wag2", new wag2_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WAG2_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/wag3.hpp b/src/boost/geometry/extensions/gis/projections/proj/wag3.hpp
new file mode 100644
index 0000000..ecc4ce7
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/wag3.hpp
@@ -0,0 +1,148 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace wag3{
+ static const double TWOTHIRD = 0.6666666666666666666667;
+
+ struct par_wag3
+ {
+ double C_x;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_wag3_spheroid : public base_t_fi<base_wag3_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_wag3 m_proj_parm;
+
+ inline base_wag3_spheroid(const Parameters& par)
+ : base_t_fi<base_wag3_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = this->m_proj_parm.C_x * lp_lon * cos(TWOTHIRD * lp_lat);
+ xy_y = lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y;
+ lp_lon = xy_x / (this->m_proj_parm.C_x * cos(TWOTHIRD * lp_lat));
+ }
+ };
+
+ // Wagner III
+ template <typename Parameters>
+ void setup_wag3(Parameters& par, par_wag3& proj_parm)
+ {
+ double ts;
+ ts = pj_param(par.params, "rlat_ts").f;
+ proj_parm.C_x = cos(ts) / cos(2.*ts/3.);
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::wag3
+ #endif // doxygen
+
+ /*!
+ \brief Wagner III projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - lat_ts=
+ \par Example
+ \image html ex_wag3.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wag3_spheroid : public detail::wag3::base_wag3_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wag3_spheroid(const Parameters& par) : detail::wag3::base_wag3_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::wag3::setup_wag3(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wag3_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wag3_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void wag3_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("wag3", new wag3_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WAG3_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/wag7.hpp b/src/boost/geometry/extensions/gis/projections/proj/wag7.hpp
new file mode 100644
index 0000000..b957c99
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/wag7.hpp
@@ -0,0 +1,137 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace wag7{
+
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_wag7_spheroid : public base_t_f<base_wag7_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+
+ inline base_wag7_spheroid(const Parameters& par)
+ : base_t_f<base_wag7_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double theta, ct, D;
+
+ theta = asin(xy_y = 0.90630778703664996 * sin(lp_lat));
+ xy_x = 2.66723 * (ct = cos(theta)) * sin(lp_lon /= 3.);
+ xy_y *= 1.24104 * (D = 1/(sqrt(0.5 * (1 + ct * cos(lp_lon)))));
+ xy_x *= D;
+ }
+ };
+
+ // Wagner VII
+ template <typename Parameters>
+ void setup_wag7(Parameters& par)
+ {
+ // par.fwd = s_forward;
+ // par.inv = 0;
+ par.es = 0.;
+ }
+
+ }} // namespace detail::wag7
+ #endif // doxygen
+
+ /*!
+ \brief Wagner VII projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Miscellaneous
+ - Spheroid
+ - no inverse
+ \par Example
+ \image html ex_wag7.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wag7_spheroid : public detail::wag7::base_wag7_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wag7_spheroid(const Parameters& par) : detail::wag7::base_wag7_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::wag7::setup_wag7(this->m_par);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wag7_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<wag7_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void wag7_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("wag7", new wag7_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WAG7_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/wink1.hpp b/src/boost/geometry/extensions/gis/projections/proj/wink1.hpp
new file mode 100644
index 0000000..38d8156
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/wink1.hpp
@@ -0,0 +1,145 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace wink1{
+
+ struct par_wink1
+ {
+ double cosphi1;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_wink1_spheroid : public base_t_fi<base_wink1_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_wink1 m_proj_parm;
+
+ inline base_wink1_spheroid(const Parameters& par)
+ : base_t_fi<base_wink1_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ xy_x = .5 * lp_lon * (this->m_proj_parm.cosphi1 + cos(lp_lat));
+ xy_y = lp_lat;
+ }
+
+ inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
+ {
+ lp_lat = xy_y;
+ lp_lon = 2. * xy_x / (this->m_proj_parm.cosphi1 + cos(lp_lat));
+ }
+ };
+
+ // Winkel I
+ template <typename Parameters>
+ void setup_wink1(Parameters& par, par_wink1& proj_parm)
+ {
+ proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_ts").f);
+ par.es = 0.;
+ // par.inv = s_inverse;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::wink1
+ #endif // doxygen
+
+ /*!
+ \brief Winkel I projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - lat_ts=
+ \par Example
+ \image html ex_wink1.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wink1_spheroid : public detail::wink1::base_wink1_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wink1_spheroid(const Parameters& par) : detail::wink1::base_wink1_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::wink1::setup_wink1(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wink1_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_fi<wink1_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void wink1_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("wink1", new wink1_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WINK1_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/proj/wink2.hpp b/src/boost/geometry/extensions/gis/projections/proj/wink2.hpp
new file mode 100644
index 0000000..a7d48f0
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/proj/wink2.hpp
@@ -0,0 +1,159 @@
+#ifndef BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP
+
+// Boost.Geometry - extensions-gis-projections (based on PROJ4)
+// This file is automatically generated. DO NOT EDIT.
+
+// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is converted from PROJ4, http://trac.osgeo.org/proj
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Boost.Geometry by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <boost/math/special_functions/hypot.hpp>
+
+#include <boost/geometry/extensions/gis/projections/impl/base_static.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/base_dynamic.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+#include <boost/geometry/extensions/gis/projections/impl/factory_entry.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail { namespace wink2{
+ static const int MAX_ITER = 10;
+ static const double LOOP_TOL = 1e-7;
+ static const double TWO_D_PI = 0.636619772367581343;
+
+ struct par_wink2
+ {
+ double cosphi1;
+ };
+
+ // template class, using CRTP to implement forward/inverse
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ struct base_wink2_spheroid : public base_t_f<base_wink2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>
+ {
+
+ typedef double geographic_type;
+ typedef double cartesian_type;
+
+ par_wink2 m_proj_parm;
+
+ inline base_wink2_spheroid(const Parameters& par)
+ : base_t_f<base_wink2_spheroid<Geographic, Cartesian, Parameters>,
+ Geographic, Cartesian, Parameters>(*this, par) {}
+
+ inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
+ {
+ double k, V;
+ int i;
+
+ xy_y = lp_lat * TWO_D_PI;
+ k = PI * sin(lp_lat);
+ lp_lat *= 1.8;
+ for (i = MAX_ITER; i ; --i) {
+ lp_lat -= V = (lp_lat + sin(lp_lat) - k) /
+ (1. + cos(lp_lat));
+ if (fabs(V) < LOOP_TOL)
+ break;
+ }
+ if (!i)
+ lp_lat = (lp_lat < 0.) ? -HALFPI : HALFPI;
+ else
+ lp_lat *= 0.5;
+ xy_x = 0.5 * lp_lon * (cos(lp_lat) + this->m_proj_parm.cosphi1);
+ xy_y = FORTPI * (sin(lp_lat) + xy_y);
+ }
+ };
+
+ // Winkel II
+ template <typename Parameters>
+ void setup_wink2(Parameters& par, par_wink2& proj_parm)
+ {
+ proj_parm.cosphi1 = cos(pj_param(par.params, "rlat_1").f);
+ par.es = 0.;
+ // par.inv = 0;
+ // par.fwd = s_forward;
+ }
+
+ }} // namespace detail::wink2
+ #endif // doxygen
+
+ /*!
+ \brief Winkel II projection
+ \ingroup projections
+ \tparam Geographic latlong point type
+ \tparam Cartesian xy point type
+ \tparam Parameters parameter type
+ \par Projection characteristics
+ - Pseudocylindrical
+ - Spheroid
+ - no inverse
+ - lat_1=
+ \par Example
+ \image html ex_wink2.gif
+ */
+ template <typename Geographic, typename Cartesian, typename Parameters = parameters>
+ struct wink2_spheroid : public detail::wink2::base_wink2_spheroid<Geographic, Cartesian, Parameters>
+ {
+ inline wink2_spheroid(const Parameters& par) : detail::wink2::base_wink2_spheroid<Geographic, Cartesian, Parameters>(par)
+ {
+ detail::wink2::setup_wink2(this->m_par, this->m_proj_parm);
+ }
+ };
+
+ #ifndef DOXYGEN_NO_DETAIL
+ namespace detail
+ {
+
+ // Factory entry(s)
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ class wink2_entry : public detail::factory_entry<Geographic, Cartesian, Parameters>
+ {
+ public :
+ virtual projection<Geographic, Cartesian>* create_new(const Parameters& par) const
+ {
+ return new base_v_f<wink2_spheroid<Geographic, Cartesian, Parameters>, Geographic, Cartesian, Parameters>(par);
+ }
+ };
+
+ template <typename Geographic, typename Cartesian, typename Parameters>
+ inline void wink2_init(detail::base_factory<Geographic, Cartesian, Parameters>& factory)
+ {
+ factory.add_to_factory("wink2", new wink2_entry<Geographic, Cartesian, Parameters>);
+ }
+
+ } // namespace detail
+ #endif // doxygen
+
+}}} // namespace boost::geometry::projection
+
+#endif // BOOST_GEOMETRY_PROJECTIONS_WINK2_HPP
+
diff --git a/src/boost/geometry/extensions/gis/projections/project_inverse_transformer.hpp b/src/boost/geometry/extensions/gis/projections/project_inverse_transformer.hpp
new file mode 100644
index 0000000..832fa8a
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/project_inverse_transformer.hpp
@@ -0,0 +1,73 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGY_PROJECT_INVERSE_TRANSFORMER_HPP
+#define BOOST_GEOMETRY_STRATEGY_PROJECT_INVERSE_TRANSFORMER_HPP
+
+
+#include <boost/shared_ptr.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/extensions/gis/projections/factory.hpp>
+#include <boost/geometry/extensions/gis/projections/parameters.hpp>
+
+
+namespace boost { namespace geometry { namespace projection
+{
+
+
+/*!
+ \brief Transformation strategy to do transform using a Map Projection
+ \ingroup transform
+ \tparam Cartesian first point type
+ \tparam LatLong second point type
+ */
+template <typename Cartesian, typename LatLong>
+struct project_inverse_transformer
+{
+ typedef boost::shared_ptr<projection<LatLong, Cartesian> > projection_ptr;
+
+ projection_ptr m_prj;
+
+ /// Constructor using a shared-pointer-to-projection_ptr
+ inline project_inverse_transformer(projection_ptr& prj)
+ : m_prj(prj)
+ {}
+
+ /// Constructor using a string
+ inline project_inverse_transformer(std::string const& par)
+ {
+ factory<LatLong, Cartesian, parameters> fac;
+ m_prj.reset(fac.create_new(init(par)));
+ }
+
+ /// Constructor using Parameters
+ template <typename Parameters>
+ inline project_inverse_transformer(Parameters const& par)
+ {
+ factory<LatLong, Cartesian, Parameters> fac;
+ m_prj.reset(fac.create_new(par));
+ }
+
+ /// Transform operator
+ inline bool apply(Cartesian const& p1, LatLong& p2) const
+ {
+ // Latlong (LL -> XY) will be projected, rest will be copied.
+ // So first copy third or higher dimensions
+ geometry::detail::convert::point_to_point<Cartesian, LatLong, 2,
+ geometry::dimension<Cartesian>::value> ::copy(p1, p2);
+ return m_prj->inverse(p1, p2);
+ }
+
+};
+
+}}} // namespace boost::geometry::projection
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_PROJECT_INVERSE_TRANSFORMER_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/project_transformer.hpp b/src/boost/geometry/extensions/gis/projections/project_transformer.hpp
new file mode 100644
index 0000000..02ddff4
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/project_transformer.hpp
@@ -0,0 +1,65 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGY_PROJECT_TRANSFORMER_HPP
+#define BOOST_GEOMETRY_STRATEGY_PROJECT_TRANSFORMER_HPP
+
+
+#include <boost/shared_ptr.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/extensions/gis/projections/factory.hpp>
+#include <boost/geometry/extensions/gis/projections/parameters.hpp>
+
+
+
+namespace boost { namespace geometry { namespace projection
+{
+/*!
+ \brief Transformation strategy to do transform using a Map Projection
+ \ingroup transform
+ \tparam LatLong first point type
+ \tparam Cartesian second point type
+
+ See also \link p03_projmap_example.cpp the projmap example \endlink
+ where this last one plus a transformation using a projection are used.
+
+ */
+template <typename LatLong, typename Cartesian>
+struct project_transformer
+{
+ typedef boost::shared_ptr<projection<LatLong, Cartesian> > projection_ptr;
+
+ projection_ptr m_prj;
+
+ inline project_transformer(projection_ptr& prj)
+ : m_prj(prj)
+ {}
+
+ inline project_transformer(std::string const& par)
+ {
+ factory<LatLong, Cartesian, parameters> fac;
+ m_prj.reset(fac.create_new(init(par)));
+ }
+
+ inline bool apply(LatLong const& p1, Cartesian& p2) const
+ {
+ // Latlong (LatLong -> Cartesian) will be projected, rest will be copied.
+ // So first copy third or higher dimensions
+ geometry::detail::convert::point_to_point<LatLong, Cartesian, 2,
+ geometry::dimension<Cartesian>::value> ::copy(p1, p2);
+ return m_prj->forward(p1, p2);
+ }
+
+};
+
+}}} // namespace boost::geometry::projection
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_PROJECT_TRANSFORMER_HPP
diff --git a/src/boost/geometry/extensions/gis/projections/projection.hpp b/src/boost/geometry/extensions/gis/projections/projection.hpp
new file mode 100644
index 0000000..fc0dfcd
--- /dev/null
+++ b/src/boost/geometry/extensions/gis/projections/projection.hpp
@@ -0,0 +1,65 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_PROJECTIONS_PROJECTION_HPP
+#define BOOST_GEOMETRY_PROJECTIONS_PROJECTION_HPP
+
+
+#include <string>
+#include <boost/geometry/extensions/gis/projections/impl/projects.hpp>
+
+namespace boost { namespace geometry { namespace projection
+{
+
+/*!
+ \brief projection virtual base class
+ \details class containing virtual methods
+ \ingroup projection
+ \tparam LL latlong point type
+ \tparam XY xy point type
+*/
+
+template <typename LL, typename XY>
+class projection
+{
+ protected :
+ // see comment above
+ //typedef typename geometry::coordinate_type<LL>::type LL_T;
+ //typedef typename geometry::coordinate_type<XY>::type XY_T;
+ typedef double LL_T;
+ typedef double XY_T;
+
+ public :
+ /// Forward projection, from Latitude-Longitude to Cartesian
+ virtual bool forward(LL const& lp, XY& xy) const = 0;
+
+ /// Inverse projection, from Cartesian to Latitude-Longitude
+ virtual bool inverse(XY const& xy, LL& lp) const = 0;
+
+ /// Forward projection using lon / lat and x / y separately
+ virtual void fwd(LL_T& lp_lon, LL_T& lp_lat, XY_T& xy_x, XY_T& xy_y) const = 0;
+
+ /// Inverse projection using x / y and lon / lat
+ virtual void inv(XY_T& xy_x, XY_T& xy_y, LL_T& lp_lon, LL_T& lp_lat) const = 0;
+
+ /// Returns name of projection
+ virtual std::string name() const = 0;
+
+ /// Returns parameters of projection
+ virtual parameters params() const = 0;
+
+ virtual ~projection() {}
+
+};
+
+}}} // namespace boost::geometry::projection
+
+
+
+#endif
+
diff --git a/src/boost/geometry/extensions/index/rtree/helpers.hpp b/src/boost/geometry/extensions/index/rtree/helpers.hpp
new file mode 100644
index 0000000..45a71f3
--- /dev/null
+++ b/src/boost/geometry/extensions/index/rtree/helpers.hpp
@@ -0,0 +1,68 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Boost.SpatialIndex - geometry helper functions
+//
+// Copyright 2008 Federico J. Fernandez.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GGL_INDEX_RTREE_HELPERS_HPP
+#define BOOST_GEOMETRY_GGL_INDEX_RTREE_HELPERS_HPP
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+/**
+ * \brief Given two boxes, returns the minimal box that contains them
+ */
+// TODO: use geometry::expand
+template <typename Box>
+inline Box enlarge_box(Box const& b1, Box const& b2)
+{
+ // TODO: mloskot - Refactor to readable form. Fix VC++8.0 min/max warnings:
+ // warning C4002: too many actual parameters for macro 'min
+
+ typedef typename geometry::point_type<Box>::type point_type;
+
+ point_type pmin(
+ geometry::get<min_corner, 0>(b1) < geometry::get<min_corner, 0>(b2)
+ ? geometry::get<min_corner, 0>(b1) : geometry::get<min_corner, 0>(b2),
+ geometry::get<min_corner, 1>(b1) < geometry::get<min_corner, 1>(b2)
+ ? geometry::get<min_corner, 1>(b1) : geometry::get<min_corner, 1>(b2));
+
+ point_type pmax(
+ geometry::get<max_corner, 0>(b1) > geometry::get<max_corner, 0>(b2)
+ ? geometry::get<max_corner, 0>(b1) : geometry::get<max_corner, 0>(b2),
+ geometry::get<max_corner, 1>(b1) > geometry::get<max_corner, 1>(b2)
+ ? geometry::get<max_corner, 1>(b1) : geometry::get<max_corner, 1>(b2));
+
+ return Box(pmin, pmax);
+}
+
+/**
+ * \brief Compute the area of the union of b1 and b2
+ */
+template <typename Box>
+inline typename default_area_result<Box>::type compute_union_area(Box const& b1, Box const& b2)
+{
+ Box enlarged_box = enlarge_box(b1, b2);
+ return geometry::area(enlarged_box);
+}
+
+/**
+ * \brief Checks if boxes intersects
+ */
+// TODO: move to geometry::intersects
+template <typename Box>
+inline bool is_overlapping(Box const& b1, Box const& b2)
+{
+ return ! geometry::disjoint(b1, b2);
+}
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_GGL_INDEX_RTREE_HELPERS_HPP
diff --git a/src/boost/geometry/extensions/index/rtree/rtree.hpp b/src/boost/geometry/extensions/index/rtree/rtree.hpp
new file mode 100644
index 0000000..4a06bd6
--- /dev/null
+++ b/src/boost/geometry/extensions/index/rtree/rtree.hpp
@@ -0,0 +1,774 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Boost.SpatialIndex - rtree implementation
+//
+// Copyright 2008 Federico J. Fernandez.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_HPP
+
+#include <cstddef>
+#include <iostream> // TODO: Remove if print() is removed
+#include <stdexcept>
+#include <utility>
+#include <vector>
+
+#include <boost/concept_check.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+
+#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
+#include <boost/geometry/extensions/index/rtree/rtree_leaf.hpp>
+
+namespace boost { namespace geometry { namespace index
+{
+
+template <typename Box, typename Value >
+class rtree
+{
+public:
+
+ typedef boost::shared_ptr<rtree_node<Box, Value> > node_pointer;
+ typedef boost::shared_ptr<rtree_leaf<Box, Value> > leaf_pointer;
+
+ /**
+ * \brief Creates a rtree with 'maximum' elements per node and 'minimum'.
+ */
+ rtree(unsigned int const& maximum, unsigned int const& minimum)
+ : m_count(0)
+ , m_min_elems_per_node(minimum)
+ , m_max_elems_per_node(maximum)
+ , m_root(new rtree_node<Box, Value>(node_pointer(), 1))
+ {
+ }
+
+ /**
+ * \brief Creates a rtree with maximum elements per node
+ * and minimum (box is ignored).
+ */
+ rtree(Box const& box, unsigned int const& maximum, unsigned int const& minimum)
+ : m_count(0)
+ , m_min_elems_per_node(minimum)
+ , m_max_elems_per_node(maximum)
+ , m_root(new rtree_node<Box, Value>(node_pointer(), 1))
+ {
+ boost::ignore_unused_variable_warning(box);
+ }
+
+ /**
+ * \brief destructor (virtual because we have virtual functions)
+ */
+ virtual ~rtree() {}
+
+
+ /**
+ * \brief Remove elements inside the 'box'
+ */
+ inline void remove(Box const& box)
+ {
+ try
+ {
+ node_pointer leaf(choose_exact_leaf(box));
+ typename rtree_leaf<Box, Value>::leaf_map q_leaves;
+
+ leaf->remove(box);
+
+ if (leaf->elements() < m_min_elems_per_node && elements() > m_min_elems_per_node)
+ {
+ q_leaves = leaf->get_leaves();
+
+ // we remove the leaf_node in the parent node because now it's empty
+ leaf->get_parent()->remove(leaf->get_parent()->get_box(leaf));
+ }
+
+ typename rtree_node<Box, Value>::node_map q_nodes;
+ condense_tree(leaf, q_nodes);
+
+ std::vector<std::pair<Box, Value> > s;
+ for (typename rtree_node<Box, Value>::node_map::const_iterator it = q_nodes.begin();
+ it != q_nodes.end(); ++it)
+ {
+ typename rtree_leaf<Box, Value>::leaf_map leaves = it->second->get_leaves();
+
+ // reinserting leaves from nodes
+ for (typename rtree_leaf<Box, Value>::leaf_map::const_iterator itl = leaves.begin();
+ itl != leaves.end(); ++itl)
+ {
+ s.push_back(*itl);
+ }
+ }
+
+ for (typename std::vector<std::pair<Box, Value> >::const_iterator it = s.begin(); it != s.end(); ++it)
+ {
+ m_count--;
+ insert(it->first, it->second);
+ }
+
+ // if the root has only one child and the child is not a leaf,
+ // make it the root
+ if (m_root->elements() == 1)
+ {
+ if (!m_root->first_element()->is_leaf())
+ {
+ m_root = m_root->first_element();
+ }
+ }
+ // reinserting leaves
+ for (typename rtree_leaf<Box, Value>::leaf_map::const_iterator it = q_leaves.begin();
+ it != q_leaves.end(); ++it)
+ {
+ m_count--;
+ insert(it->first, it->second);
+ }
+
+ m_count--;
+ }
+ catch(std::logic_error & e)
+ {
+ // TODO: mloskot - replace with Boost.Geometry exception
+
+ // not found
+ std::cerr << e.what() << std::endl;
+ return;
+ }
+ }
+
+ /**
+ * \brief Remove element inside the box with value
+ */
+ void remove(Box const& box, Value const& value)
+ {
+ try
+ {
+ node_pointer leaf;
+
+ // find possible leaves
+ typedef typename std::vector<node_pointer > node_type;
+ node_type nodes;
+ m_root->find_leaves(box, nodes);
+
+ // refine the result
+ for (typename node_type::const_iterator it = nodes.begin(); it != nodes.end(); ++it)
+ {
+ leaf = *it;
+ try
+ {
+ leaf->remove(value);
+ break;
+ } catch (...)
+ {
+ leaf = node_pointer();
+ }
+ }
+
+ if (!leaf)
+ return;
+
+ typename rtree_leaf < Box, Value >::leaf_map q_leaves;
+
+ if (leaf->elements() < m_min_elems_per_node && elements() > m_min_elems_per_node)
+ {
+ q_leaves = leaf->get_leaves();
+
+ // we remove the leaf_node in the parent node because now it's empty
+ leaf->get_parent()->remove(leaf->get_parent()->get_box(leaf));
+ }
+
+ typename rtree_node<Box, Value>::node_map q_nodes;
+ condense_tree(leaf, q_nodes);
+
+ std::vector<std::pair<Box, Value> > s;
+ for (typename rtree_node<Box, Value>::node_map::const_iterator it = q_nodes.begin();
+ it != q_nodes.end(); ++it)
+ {
+ typename rtree_leaf<Box, Value>::leaf_map leaves = it->second->get_leaves();
+
+ // reinserting leaves from nodes
+ for (typename rtree_leaf<Box, Value>::leaf_map::const_iterator itl = leaves.begin();
+ itl != leaves.end(); ++itl)
+ {
+ s.push_back(*itl);
+ }
+ }
+
+ for (typename std::vector<std::pair<Box, Value> >::const_iterator it = s.begin(); it != s.end(); ++it)
+ {
+ m_count--;
+ insert(it->first, it->second);
+ }
+
+ // if the root has only one child and the child is not a leaf,
+ // make it the root
+ if (m_root->elements() == 1)
+ {
+ if (!m_root->first_element()->is_leaf())
+ {
+ m_root = m_root->first_element();
+ }
+ }
+
+ // reinserting leaves
+ for (typename rtree_leaf<Box, Value>::leaf_map::const_iterator it = q_leaves.begin();
+ it != q_leaves.end(); ++it)
+ {
+ m_count--;
+ insert(it->first, it->second);
+ }
+
+ m_count--;
+
+ }
+ catch(std::logic_error & e)
+ {
+ // TODO: mloskot - ggl exception
+
+ // not found
+ std::cerr << e.what() << std::endl;
+ return;
+ }
+ }
+
+ /**
+ * \brief Returns the number of elements.
+ */
+ inline unsigned int elements() const
+ {
+ return m_count;
+ }
+
+
+ /**
+ * \brief Inserts an element with 'box' as key with value.
+ */
+ inline void insert(Box const& box, Value const& value)
+ {
+ m_count++;
+
+ node_pointer leaf(choose_corresponding_leaf(box));
+
+ // check if the selected leaf is full to do the split if necessary
+ if (leaf->elements() >= m_max_elems_per_node)
+ {
+ leaf->insert(box, value);
+
+ // split!
+ node_pointer n1(new rtree_leaf<Box, Value>(leaf->get_parent()));
+ node_pointer n2(new rtree_leaf<Box, Value>(leaf->get_parent()));
+
+ split_node(leaf, n1, n2);
+ adjust_tree(leaf, n1, n2);
+ }
+ else
+ {
+ leaf->insert(box, value);
+ adjust_tree(leaf);
+ }
+ }
+
+
+ /**
+ * \brief Returns all the values inside 'box'
+ */
+ inline std::deque<Value> find(Box const& box) const
+ {
+ std::deque<Value> result;
+ m_root->find(box, result, false);
+ return result;
+ }
+
+ /**
+ * \brief Print Rtree (mainly for debug)
+ */
+ inline void print()
+ {
+ std::cerr << "===================================" << std::endl;
+ std::cerr << " Min/Max: " << m_min_elems_per_node << " / " << m_max_elems_per_node << std::endl;
+ std::cerr << "Leaves: " << m_root->get_leaves().size() << std::endl;
+ m_root->print();
+ std::cerr << "===================================" << std::endl;
+ }
+
+private:
+
+ /// number of elements
+ unsigned int m_count;
+
+ /// minimum number of elements per node
+ unsigned int m_min_elems_per_node;
+
+ /// maximum number of elements per node
+ unsigned int m_max_elems_per_node;
+
+ /// tree root
+ node_pointer m_root;
+
+ /**
+ * \brief Reorganize the tree after a removal. It tries to
+ * join nodes with less elements than m.
+ */
+ void condense_tree(node_pointer const& leaf,
+ typename rtree_node<Box, Value>::node_map& q_nodes)
+ {
+ if (leaf.get() == m_root.get())
+ {
+ // if it's the root we are done
+ return;
+ }
+
+ node_pointer parent = leaf->get_parent();
+ parent->adjust_box(leaf);
+
+ if (parent->elements() < m_min_elems_per_node)
+ {
+ if (parent.get() == m_root.get())
+ {
+ // if the parent is underfull and it's the root we just exit
+ return;
+ }
+
+ // get the nodes that we should reinsert
+ typename rtree_node<Box, Value>::node_map this_nodes = parent->get_nodes();
+ for(typename rtree_node<Box, Value>::node_map::const_iterator it = this_nodes.begin();
+ it != this_nodes.end(); ++it)
+ {
+ q_nodes.push_back(*it);
+ }
+
+ // we remove the node in the parent node because now it should be
+ // re inserted
+ parent->get_parent()->remove(parent->get_parent()->get_box(parent));
+ }
+
+ condense_tree(parent, q_nodes);
+ }
+
+ /**
+ * \brief After an insertion splits nodes with more than 'maximum' elements.
+ */
+ inline void adjust_tree(node_pointer& node)
+ {
+ if (node.get() == m_root.get())
+ {
+ // we finished the adjust
+ return;
+ }
+
+ // as there are no splits just adjust the box of the parent and go on
+ node_pointer parent = node->get_parent();
+ parent->adjust_box(node);
+ adjust_tree(parent);
+ }
+
+ /**
+ * \brief After an insertion splits nodes with more than maximum elements
+ * (recursive step with subtrees 'n1' and 'n2' to be joined).
+ */
+ void adjust_tree(node_pointer& leaf, node_pointer& n1, node_pointer& n2)
+ {
+ // check if we are in the root and do the split
+ if (leaf.get() == m_root.get())
+ {
+ node_pointer new_root(new rtree_node<Box,Value>(node_pointer (), leaf->get_level() + 1));
+ new_root->add_node(n1->compute_box(), n1);
+ new_root->add_node(n2->compute_box(), n2);
+
+ n1->set_parent(new_root);
+ n2->set_parent(new_root);
+
+ n1->update_parent(n1);
+ n2->update_parent(n2);
+
+ m_root = new_root;
+ return;
+ }
+
+ node_pointer parent = leaf->get_parent();
+
+ parent->replace_node(leaf, n1);
+ parent->add_node(n2->compute_box(), n2);
+
+ // if parent is full, split and readjust
+ if (parent->elements() > m_max_elems_per_node)
+ {
+ node_pointer p1(new rtree_node<Box, Value>(parent->get_parent(), parent->get_level()));
+ node_pointer p2(new rtree_node<Box, Value>(parent->get_parent(), parent->get_level()));
+
+ split_node(parent, p1, p2);
+ adjust_tree(parent, p1, p2);
+ }
+ else
+ {
+ adjust_tree(parent);
+ }
+ }
+
+ /**
+ * \brief Splits 'n' in 'n1' and 'n2'
+ */
+ void split_node(node_pointer const& n, node_pointer& n1, node_pointer& n2) const
+ {
+ unsigned int seed1 = 0;
+ unsigned int seed2 = 0;
+ std::vector<Box> boxes = n->get_boxes();
+
+ n1->set_parent(n->get_parent());
+ n2->set_parent(n->get_parent());
+
+ linear_pick_seeds(n, seed1, seed2);
+
+ if (n->is_leaf())
+ {
+ n1->add_value(boxes[seed1], n->get_value(seed1));
+ n2->add_value(boxes[seed2], n->get_value(seed2));
+ }
+ else
+ {
+ n1->add_node(boxes[seed1], n->get_node(seed1));
+ n2->add_node(boxes[seed2], n->get_node(seed2));
+ }
+
+ unsigned int index = 0;
+
+ if (n->is_leaf())
+ {
+ // TODO: mloskot - add assert(node.size() >= 2); or similar
+
+ typename rtree_leaf<Box, Value>::leaf_map nodes = n->get_leaves();
+ unsigned int remaining = nodes.size() - 2;
+
+ for (typename rtree_leaf<Box, Value>::leaf_map::const_iterator it = nodes.begin();
+ it != nodes.end(); ++it, index++)
+ {
+ if (index != seed1 && index != seed2)
+ {
+ if (n1->elements() + remaining == m_min_elems_per_node)
+ {
+ n1->add_value(it->first, it->second);
+ continue;
+ }
+ if (n2->elements() + remaining == m_min_elems_per_node)
+ {
+ n2->add_value(it->first, it->second);
+ continue;
+ }
+
+ remaining--;
+
+ /// current boxes of each group
+ Box b1, b2;
+
+ /// enlarged boxes of each group
+ Box eb1, eb2;
+ b1 = n1->compute_box();
+ b2 = n2->compute_box();
+
+ /// areas
+ typedef typename coordinate_type<Box>::type coordinate_type;
+ coordinate_type b1_area, b2_area;
+ coordinate_type eb1_area, eb2_area;
+ b1_area = geometry::area(b1);
+ b2_area = geometry::area(b2);
+ eb1_area = compute_union_area(b1, it->first);
+ eb2_area = compute_union_area(b2, it->first);
+
+ if (eb1_area - b1_area > eb2_area - b2_area)
+ {
+ n2->add_value(it->first, it->second);
+ }
+ if (eb1_area - b1_area < eb2_area - b2_area)
+ {
+ n1->add_value(it->first, it->second);
+ }
+ if (eb1_area - b1_area == eb2_area - b2_area)
+ {
+ if (b1_area < b2_area)
+ {
+ n1->add_value(it->first, it->second);
+ }
+ if (b1_area > b2_area)
+ {
+ n2->add_value(it->first, it->second);
+ }
+ if (b1_area == b2_area)
+ {
+ if (n1->elements() > n2->elements())
+ {
+ n2->add_value(it->first, it->second);
+ }
+ else
+ {
+ n1->add_value(it->first, it->second);
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // TODO: mloskot - add assert(node.size() >= 2); or similar
+
+ typename rtree_node<Box, Value>::node_map nodes = n->get_nodes();
+ unsigned int remaining = nodes.size() - 2;
+ for(typename rtree_node<Box, Value>::node_map::const_iterator it = nodes.begin();
+ it != nodes.end(); ++it, index++)
+ {
+
+ if (index != seed1 && index != seed2)
+ {
+
+ if (n1->elements() + remaining == m_min_elems_per_node)
+ {
+ n1->add_node(it->first, it->second);
+ continue;
+ }
+ if (n2->elements() + remaining == m_min_elems_per_node)
+ {
+ n2->add_node(it->first, it->second);
+ continue;
+ }
+
+ remaining--;
+
+ /// current boxes of each group
+ Box b1, b2;
+
+ /// enlarged boxes of each group
+ Box eb1, eb2;
+ b1 = n1->compute_box();
+ b2 = n2->compute_box();
+
+ /// areas
+ typedef typename coordinate_type<Box>::type coordinate_type;
+ coordinate_type b1_area, b2_area;
+ coordinate_type eb1_area, eb2_area;
+ b1_area = geometry::area(b1);
+ b2_area = geometry::area(b2);
+
+ eb1_area = compute_union_area(b1, it->first);
+ eb2_area = compute_union_area(b2, it->first);
+
+ if (eb1_area - b1_area > eb2_area - b2_area)
+ {
+ n2->add_node(it->first, it->second);
+ }
+ if (eb1_area - b1_area < eb2_area - b2_area)
+ {
+ n1->add_node(it->first, it->second);
+ }
+ if (eb1_area - b1_area == eb2_area - b2_area)
+ {
+ if (b1_area < b2_area)
+ {
+ n1->add_node(it->first, it->second);
+ }
+ if (b1_area > b2_area)
+ {
+ n2->add_node(it->first, it->second);
+ }
+ if (b1_area == b2_area)
+ {
+ if (n1->elements() > n2->elements())
+ {
+ n2->add_node(it->first, it->second);
+ }
+ else
+ {
+ n1->add_node(it->first, it->second);
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ /**
+ * \brief Choose initial values for the split algorithm (linear version)
+ */
+ void linear_pick_seeds(node_pointer const& n, unsigned int &seed1, unsigned int &seed2) const
+ {
+ // get boxes from the node
+ std::vector<Box>boxes = n->get_boxes();
+ if (boxes.size() == 0)
+ {
+ // TODO: mloskot - throw ggl exception
+ throw std::logic_error("Empty Node trying to Pick Seeds");
+ }
+
+ // only two dim for now
+ // unsigned int dimensions =
+ // geometry::point_traits<Point>::coordinate_count;
+
+ // find the first two elements
+ typedef typename coordinate_type<Box>::type coordinate_type;
+ coordinate_type separation_x, separation_y;
+ unsigned int first_x, second_x;
+ unsigned int first_y, second_y;
+ find_normalized_separations<0u>(boxes, separation_x, first_x, second_x);
+ find_normalized_separations<1u>(boxes, separation_y, first_y, second_y);
+
+ if (separation_x > separation_y)
+ {
+ seed1 = first_x;
+ seed2 = second_x;
+ }
+ else
+ {
+ seed1 = first_y;
+ seed2 = second_y;
+ }
+ }
+
+ /**
+ * \brief Find distances between possible initial values for the
+ * pick_seeds algorithm.
+ */
+ template <std::size_t D, typename T>
+ void find_normalized_separations(std::vector<Box> const& boxes, T& separation,
+ unsigned int& first, unsigned int& second) const
+ {
+ if (boxes.size() < 2)
+ {
+ throw std::logic_error("At least two boxes needed to split");
+ }
+
+ // find the lowest high
+ typename std::vector<Box>::const_iterator it = boxes.begin();
+ typedef typename coordinate_type<Box>::type coordinate_type;
+ coordinate_type lowest_high = geometry::get<max_corner, D>(*it);
+ unsigned int lowest_high_index = 0;
+ unsigned int index = 1;
+ ++it;
+ for(; it != boxes.end(); ++it)
+ {
+ if (geometry::get<max_corner, D>(*it) < lowest_high)
+ {
+ lowest_high = geometry::get<max_corner, D>(*it);
+ lowest_high_index = index;
+ }
+ index++;
+ }
+
+ // find the highest low
+ coordinate_type highest_low = 0;
+ unsigned int highest_low_index = 0;
+ if (lowest_high_index == 0)
+ {
+ highest_low = geometry::get<min_corner, D>(boxes[1]);
+ highest_low_index = 1;
+ }
+ else
+ {
+ highest_low = geometry::get<min_corner, D>(boxes[0]);
+ highest_low_index = 0;
+ }
+
+ index = 0;
+ for (typename std::vector<Box>::const_iterator it = boxes.begin();
+ it != boxes.end(); ++it, index++)
+ {
+ if (geometry::get<min_corner, D>(*it) >= highest_low && index != lowest_high_index)
+ {
+ highest_low = geometry::get<min_corner, D>(*it);
+ highest_low_index = index;
+ }
+ }
+
+ // find the lowest low
+ it = boxes.begin();
+ coordinate_type lowest_low = geometry::get<min_corner, D>(*it);
+ ++it;
+ for(; it != boxes.end(); ++it)
+ {
+ if (geometry::get<min_corner, D>(*it) < lowest_low)
+ {
+ lowest_low = geometry::get<min_corner, D>(*it);
+ }
+ }
+
+ // find the highest high
+ it = boxes.begin();
+ coordinate_type highest_high = geometry::get<max_corner, D>(*it);
+ ++it;
+ for(; it != boxes.end(); ++it)
+ {
+ if (geometry::get<max_corner, D>(*it) > highest_high)
+ {
+ highest_high = geometry::get<max_corner, D>(*it);
+ }
+ }
+
+ coordinate_type const width = highest_high - lowest_low;
+
+ separation = (highest_low - lowest_high) / width;
+ first = highest_low_index;
+ second = lowest_high_index;
+ }
+
+ /**
+ * \brief Choose one of the possible leaves to make an insertion
+ */
+ inline node_pointer choose_corresponding_leaf(Box const& e)
+ {
+ node_pointer node = m_root;
+
+ // if the tree is empty add an initial leaf
+ if (m_root->elements() == 0)
+ {
+ leaf_pointer new_leaf(new rtree_leaf<Box, Value>(m_root));
+ m_root->add_leaf_node(Box (), new_leaf);
+
+ return new_leaf;
+ }
+
+ while (!node->is_leaf())
+ {
+ /// traverse node's map to see which node we should select
+ node = node->choose_node(e);
+ }
+ return node;
+ }
+
+ /**
+ * \brief Choose the exact leaf where an insertion should be done
+ */
+ node_pointer choose_exact_leaf(Box const&e) const
+ {
+ // find possible leaves
+ typedef typename std::vector<node_pointer> node_type;
+ node_type nodes;
+ m_root->find_leaves(e, nodes);
+
+ // refine the result
+ for (typename node_type::const_iterator it = nodes.begin(); it != nodes.end(); ++it)
+ {
+ typedef std::vector<std::pair<Box, Value> > leaves_type;
+ leaves_type leaves = (*it)->get_leaves();
+
+ for (typename leaves_type::const_iterator itl = leaves.begin();
+ itl != leaves.end(); ++itl)
+ {
+
+ if (itl->first.max_corner() == e.max_corner()
+ && itl->first.min_corner() == e.min_corner())
+ {
+ return *it;
+ }
+ }
+ }
+
+ // TODO: mloskot - ggl exception
+ throw std::logic_error("Leaf not found");
+ }
+};
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_HPP
+
diff --git a/src/boost/geometry/extensions/index/rtree/rtree_leaf.hpp b/src/boost/geometry/extensions/index/rtree/rtree_leaf.hpp
new file mode 100644
index 0000000..95d1a86
--- /dev/null
+++ b/src/boost/geometry/extensions/index/rtree/rtree_leaf.hpp
@@ -0,0 +1,253 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Boost.SpatialIndex - rtree leaf implementation
+//
+// Copyright 2008 Federico J. Fernandez.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_LEAF_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_LEAF_HPP
+
+#include <deque>
+#include <iostream> // TODO: Remove if print() is removed
+#include <stdexcept>
+#include <utility>
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+
+#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
+
+namespace boost { namespace geometry { namespace index
+{
+
+template <typename Box, typename Value >
+class rtree_leaf : public rtree_node<Box, Value>
+{
+public:
+
+ /// container type for the leaves
+ typedef boost::shared_ptr<rtree_node<Box, Value> > node_pointer;
+ typedef std::vector<std::pair<Box, Value> > leaf_map;
+
+ /**
+ * \brief Creates an empty leaf
+ */
+ inline rtree_leaf()
+ {
+ }
+
+ /**
+ * \brief Creates a new leaf, with 'parent' as parent
+ */
+ inline rtree_leaf(node_pointer const& parent)
+ : rtree_node<Box, Value> (parent, 0)
+ {
+ }
+
+ /**
+ * \brief Search for elements in 'box' in the Rtree. Add them to 'result'.
+ * If exact_match is true only return the elements having as
+ * key the 'box'. Otherwise return everything inside 'box'.
+ */
+ virtual void find(Box const& box, std::deque<Value>& result, bool const exact_match)
+ {
+ for (typename leaf_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (exact_match)
+ {
+ if (geometry::equals(it->first, box))
+ {
+ result.push_back(it->second);
+ }
+ }
+ else
+ {
+ if (is_overlapping(it->first, box))
+ {
+ result.push_back(it->second);
+ }
+ }
+ }
+ }
+
+ /**
+ * \brief Compute bounding box for this leaf
+ */
+ virtual Box compute_box() const
+ {
+ if (m_nodes.empty())
+ {
+ return Box ();
+ }
+
+ Box r;
+ geometry::assign_inverse(r);
+ for(typename leaf_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ geometry::expand(r, it->first);
+ }
+ return r;
+ }
+
+ /**
+ * \brief True if we are a leaf
+ */
+ virtual bool is_leaf() const
+ {
+ return true;
+ }
+
+ /**
+ * \brief Number of elements in the tree
+ */
+ virtual unsigned int elements() const
+ {
+ return m_nodes.size();
+ }
+
+ /**
+ * \brief Insert a new element, with key 'box' and value 'v'
+ */
+ virtual void insert(Box const& box, Value const& v)
+ {
+ m_nodes.push_back(std::make_pair(box, v));
+ }
+
+ /**
+ * \brief Proyect leaves of this node.
+ */
+ virtual std::vector< std::pair<Box, Value> > get_leaves() const
+ {
+ return m_nodes;
+ }
+
+ /**
+ * \brief Add a new child (node) to this node
+ */
+ virtual void add_node(Box const&, node_pointer const&)
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Can't add node to leaf node.");
+ }
+
+ /**
+ * \brief Add a new leaf to this node
+ */
+ virtual void add_value(Box const& box, Value const& v)
+ {
+ m_nodes.push_back(std::make_pair(box, v));
+ }
+
+
+ /**
+ * \brief Proyect value in position 'index' in the nodes container
+ */
+ virtual Value get_value(unsigned int index) const
+ {
+ return m_nodes[index].second;
+ }
+
+ /**
+ * \brief Box projector for leaf
+ */
+ virtual Box get_box(unsigned int index) const
+ {
+ return m_nodes[index].first;
+ }
+
+ /**
+ * \brief Remove value with key 'box' in this leaf
+ */
+ virtual void remove(Box const& box)
+ {
+
+ for (typename leaf_map::iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (geometry::equals(it->first, box))
+ {
+ m_nodes.erase(it);
+ return;
+ }
+ }
+
+ // TODO: mloskot - use GGL exception
+ throw std::logic_error("Node not found.");
+ }
+
+ /**
+ * \brief Remove value in this leaf
+ */
+ virtual void remove(Value const& v)
+ {
+ for (typename leaf_map::iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (it->second == v)
+ {
+ m_nodes.erase(it);
+ return;
+ }
+ }
+
+ // TODO: mloskot - use GGL exception
+ throw std::logic_error("Node not found.");
+ }
+
+ /**
+ * \brief Proyect boxes from this node
+ */
+ virtual std::vector<Box> get_boxes() const
+ {
+ std::vector<Box> result;
+ for (typename leaf_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ result.push_back(it->first);
+ }
+
+ return result;
+ }
+
+ /**
+ * \brief Print leaf (mainly for debug)
+ */
+ virtual void print() const
+ {
+ std::cerr << "\t" << " --> Leaf --------" << std::endl;
+ std::cerr << "\t" << " Size: " << m_nodes.size() << std::endl;
+ for (typename leaf_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ std::cerr << "\t" << " | ";
+ std::cerr << "( " << geometry::get<min_corner, 0>
+ (it->first) << " , " << geometry::get<min_corner, 1>
+ (it->first) << " ) x ";
+ std::cerr << "( " << geometry::get<max_corner, 0>
+ (it->first) << " , " << geometry::get<max_corner, 1>
+ (it->first) << " )";
+ std::cerr << " -> ";
+ std::cerr << it->second;
+ std::cerr << " | " << std::endl;;
+ }
+ std::cerr << "\t" << " --< Leaf --------" << std::endl;
+ }
+
+private:
+
+ /// leaves of this node
+ leaf_map m_nodes;
+};
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_LEAF_HPP
+
diff --git a/src/boost/geometry/extensions/index/rtree/rtree_node.hpp b/src/boost/geometry/extensions/index/rtree/rtree_node.hpp
new file mode 100644
index 0000000..de35ef2
--- /dev/null
+++ b/src/boost/geometry/extensions/index/rtree/rtree_node.hpp
@@ -0,0 +1,493 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Boost.SpatialIndex - rtree node implementation
+//
+// Copyright 2008 Federico J. Fernandez.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_NODE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_NODE_HPP
+
+#include <deque>
+#include <iostream> // TODO: Remove if print() is removed
+#include <stdexcept>
+#include <utility>
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+
+#include <boost/geometry/extensions/index/rtree/helpers.hpp>
+
+namespace boost { namespace geometry { namespace index
+{
+
+/// forward declaration
+template <typename Box, typename Value>
+class rtree_leaf;
+
+template <typename Box, typename Value>
+class rtree_node
+{
+public:
+
+ typedef boost::shared_ptr<rtree_node<Box, Value> > node_pointer;
+ typedef boost::shared_ptr<rtree_leaf<Box, Value> > leaf_pointer;
+
+ /// type for the node map
+ typedef std::vector<std::pair<Box, node_pointer > > node_map;
+
+ /**
+ * \brief Creates a default node (needed for the containers)
+ */
+ rtree_node()
+ {
+ }
+
+ /**
+ * \brief Creates a node with 'parent' as parent and 'level' as its level
+ */
+ rtree_node(node_pointer const& parent, unsigned int const& level)
+ : m_parent(parent), m_level(level)
+ {
+ }
+
+ /**
+ * \brief destructor (virtual because we have virtual functions)
+ */
+ virtual ~rtree_node()
+ {
+ }
+
+ /**
+ * \brief Level projector
+ */
+ virtual unsigned int get_level() const
+ {
+ return m_level;
+ }
+
+ /**
+ * \brief Number of elements in the subtree
+ */
+ virtual unsigned int elements() const
+ {
+ return m_nodes.size();
+ }
+
+ /**
+ * \brief Project first element, to replace root in case of condensing
+ */
+ inline node_pointer first_element() const
+ {
+ if (0 == m_nodes.size())
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("first_element in empty node");
+ }
+ return m_nodes.begin()->second;
+ }
+
+ /**
+ * \brief True if it is a leaf node
+ */
+ virtual bool is_leaf() const
+ {
+ return false;
+ }
+
+ /**
+ * \brief Proyector for the 'i' node
+ */
+ node_pointer get_node(unsigned int index)
+ {
+ return m_nodes[index].second;
+ }
+
+ /**
+ * \brief Search for elements in 'box' in the Rtree. Add them to 'result'.
+ * If exact_match is true only return the elements having as
+ * key the box 'box'. Otherwise return everything inside 'box'.
+ */
+ virtual void find(Box const& box, std::deque<Value>& result, bool const exact_match)
+ {
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (is_overlapping(it->first, box))
+ {
+ it->second->find(box, result, exact_match);
+ }
+ }
+ }
+
+ /**
+ * \brief Return in 'result' all the leaves inside 'box'
+ */
+ void find_leaves(Box const& box, typename std::vector<node_pointer>& result) const
+ {
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (is_overlapping(it->first, box))
+ {
+ if (it->second->is_leaf())
+ {
+ result.push_back(it->second);
+ }
+ else
+ {
+ it->second->find_leaves(box, result);
+ }
+ }
+ }
+ }
+
+ /**
+ * \brief Compute bounding box for this node
+ */
+ virtual Box compute_box() const
+ {
+ if (m_nodes.empty())
+ {
+ return Box();
+ }
+
+ Box result;
+ geometry::assign_inverse(result);
+ for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ geometry::expand(result, it->first);
+ }
+
+ return result;
+ }
+
+ /**
+ * \brief Insert a value (not allowed for a node, only on leaves)
+ */
+ virtual void insert(Box const&, Value const&)
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Insert in node!");
+ }
+
+ /**
+ * \brief Get the envelopes of a node
+ */
+ virtual std::vector<Box> get_boxes() const
+ {
+ std::vector<Box> result;
+ for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ result.push_back(it->first);
+ }
+ return result;
+ }
+
+ /**
+ * \brief Recompute the bounding box
+ */
+ void adjust_box(node_pointer const& node)
+ {
+ unsigned int index = 0;
+ for (typename node_map::iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it, index++)
+ {
+ if (it->second.get() == node.get())
+ {
+ m_nodes[index] = std::make_pair(node->compute_box(), node);
+ return;
+ }
+ }
+ }
+
+ /**
+ * \brief Remove elements inside the 'box'
+ */
+ virtual void remove(Box const& box)
+ {
+ for (typename node_map::iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (geometry::equals(it->first, box))
+ {
+ m_nodes.erase(it);
+ return;
+ }
+ }
+ }
+
+ /**
+ * \brief Remove value in this leaf
+ */
+ virtual void remove(Value const&)
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Can't remove a non-leaf node by value.");
+ }
+
+ /**
+ * \brief Replace the node in the m_nodes vector and recompute the box
+ */
+ void replace_node(node_pointer const& leaf, node_pointer& new_leaf)
+ {
+ unsigned int index = 0;
+ for(typename node_map::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it, index++)
+ {
+ if (it->second.get() == leaf.get())
+ {
+ m_nodes[index] = std::make_pair(new_leaf->compute_box(), new_leaf);
+ new_leaf->update_parent(new_leaf);
+ return;
+ }
+ }
+
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Node not found.");
+ }
+
+ /**
+ * \brief Add a child to this node
+ */
+ virtual void add_node(Box const& box, node_pointer const& node)
+ {
+ m_nodes.push_back(std::make_pair(box, node));
+ node->update_parent(node);
+ }
+
+ /**
+ * \brief add a value (not allowed in nodes, only on leaves)
+ */
+ virtual void add_value(Box const&, Value const&)
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Can't add value to non-leaf node.");
+ }
+
+ /**
+ * \brief Add a child leaf to this node
+ */
+ inline void add_leaf_node(Box const& box, leaf_pointer const& leaf)
+ {
+ m_nodes.push_back(std::make_pair(box, leaf));
+ }
+
+ /**
+ * \brief Choose a node suitable for adding 'box'
+ */
+ node_pointer choose_node(Box const& box)
+ {
+ if (m_nodes.size() == 0)
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Empty node trying to choose the least enlargement node.");
+ }
+
+ typedef typename coordinate_type<Box>::type coordinate_type;
+
+ bool first = true;
+ coordinate_type min_area = 0;
+ coordinate_type min_diff_area = 0;
+ node_pointer chosen_node;
+
+ // check for the least enlargement
+ for (typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ coordinate_type const
+ diff_area = coordinate_type(compute_union_area(box, it->first))
+ - geometry::area(it->first);
+
+ if (first)
+ {
+ // it's the first time, we keep the first
+ min_diff_area = diff_area;
+ min_area = geometry::area(it->first);
+ chosen_node = it->second;
+
+ first = false;
+ }
+ else
+ {
+ if (diff_area < min_diff_area)
+ {
+ min_diff_area = diff_area;
+ min_area = geometry::area(it->first);
+ chosen_node = it->second;
+ }
+ else
+ {
+ if (diff_area == min_diff_area)
+ {
+ if (geometry::area(it->first) < min_area)
+ {
+ min_diff_area = diff_area;
+ min_area = geometry::area(it->first);
+ chosen_node = it->second;
+ }
+ }
+ }
+ }
+ }
+
+ return chosen_node;
+ }
+
+ /**
+ * \brief Empty the node
+ */
+ virtual void empty_nodes()
+ {
+ m_nodes.clear();
+ }
+
+ /**
+ * \brief Projector for parent
+ */
+ inline node_pointer get_parent() const
+ {
+ return m_parent;
+ }
+
+ /**
+ * \brief Update the parent of all the childs
+ */
+ void update_parent(node_pointer const& node)
+ {
+ for (typename node_map::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ it->second->set_parent(node);
+ }
+ }
+
+ /**
+ * \brief Set parent
+ */
+ void set_parent(node_pointer const& node)
+ {
+ m_parent = node;
+ }
+
+ /**
+ * \brief Value projector for leaf_node (not allowed for non-leaf nodes)
+ */
+ virtual Value get_value(unsigned int) const
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("No values in a non-leaf node.");
+ }
+
+ /**
+ * \brief Box projector for node 'index'
+ */
+ virtual Box get_box(unsigned int index) const
+ {
+ return m_nodes[index].first;
+ }
+
+ /**
+ * \brief Box projector for node pointed by 'leaf'
+ */
+ virtual Box get_box(node_pointer const& leaf) const
+ {
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (it->second.get() == leaf.get())
+ {
+ return it->first;
+ }
+ }
+
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Node not found");
+ }
+
+ /**
+ * \brief Children projector
+ */
+ node_map get_nodes() const
+ {
+ return m_nodes;
+ }
+
+ /**
+ * \brief Get leaves for a node
+ */
+ virtual std::vector<std::pair<Box, Value> > get_leaves() const
+ {
+ typedef std::vector<std::pair<Box, Value> > leaf_type;
+ leaf_type leaf;
+
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ leaf_type this_leaves = it->second->get_leaves();
+
+ for (typename leaf_type::iterator it_leaf = this_leaves.begin();
+ it_leaf != this_leaves.end(); ++it_leaf)
+ {
+ leaf.push_back(*it_leaf);
+ }
+ }
+
+ return leaf;
+ }
+
+ /**
+ * \brief Print Rtree subtree (mainly for debug)
+ */
+ virtual void print() const
+ {
+ std::cerr << " --> Node --------" << std::endl;
+ std::cerr << " Address: " << this << std::endl;
+ std::cerr << " Level: " << m_level << std::endl;
+ std::cerr << " Size: " << m_nodes.size() << std::endl;
+ std::cerr << " | ";
+ for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ if (this != it->second->get_parent().get())
+ {
+ std::cerr << "ERROR - " << this << " is not " << it->second->get_parent().get() << " ";
+ }
+
+ std::cerr << "( " << geometry::get<min_corner, 0>(it->first) << " , "
+ << geometry::get<min_corner, 1>(it->first) << " ) x ";
+ std::cerr << "( " << geometry::get<max_corner, 0>(it->first) << " , "
+ << geometry::get<max_corner, 1>(it->first) << " )";
+ std::cerr << " | ";
+ }
+ std::cerr << std::endl;
+ std::cerr << " --< Node --------" << std::endl;
+
+ // print child nodes
+ std::cerr << " Children: " << std::endl;
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ it->second->print();
+ }
+ }
+
+private:
+
+ /// parent node
+ node_pointer m_parent;
+
+ /// level of this node
+ // TODO: mloskot - Why not std::size_t or node_map::size_type, same with member functions?
+ unsigned int m_level;
+
+ /// child nodes
+ node_map m_nodes;
+};
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_NODE_HPP
diff --git a/src/boost/geometry/extensions/io/svg/svg_mapper.hpp b/src/boost/geometry/extensions/io/svg/svg_mapper.hpp
new file mode 100644
index 0000000..de96796
--- /dev/null
+++ b/src/boost/geometry/extensions/io/svg/svg_mapper.hpp
@@ -0,0 +1,347 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_SVG_MAPPER_HPP
+#define BOOST_GEOMETRY_IO_SVG_MAPPER_HPP
+
+#include <cstdio>
+
+#include <vector>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/strategies/transform.hpp>
+#include <boost/geometry/strategies/transform/map_transformer.hpp>
+#include <boost/geometry/views/segment_view.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/algorithms/envelope.hpp>
+#include <boost/geometry/multi/algorithms/num_points.hpp>
+
+#include <boost/geometry/extensions/io/svg/write_svg.hpp>
+
+// Helper geometries (all points are transformed to integer-points)
+#include <boost/geometry/geometries/geometries.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace svg
+{
+ typedef model::point<int, 2, cs::cartesian> svg_point_type;
+}}
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+
+template <typename GeometryTag, typename Geometry>
+struct svg_map
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (Geometry)
+ );
+};
+
+
+template <typename Point>
+struct svg_map<point_tag, Point>
+{
+ template <typename TransformStrategy>
+ static inline void apply(std::ostream& stream,
+ std::string const& style, int size,
+ Point const& point, TransformStrategy const& strategy)
+ {
+ detail::svg::svg_point_type ipoint;
+ geometry::transform(point, ipoint, strategy);
+ stream << geometry::svg(ipoint, style, size) << std::endl;
+ }
+};
+
+template <typename Box>
+struct svg_map<box_tag, Box>
+{
+ template <typename TransformStrategy>
+ static inline void apply(std::ostream& stream,
+ std::string const& style, int size,
+ Box const& box, TransformStrategy const& strategy)
+ {
+ model::box<detail::svg::svg_point_type> ibox;
+ geometry::transform(box, ibox, strategy);
+
+ stream << geometry::svg(ibox, style, size) << std::endl;
+ }
+};
+
+
+template <typename Range1, typename Range2>
+struct svg_map_range
+{
+ template <typename TransformStrategy>
+ static inline void apply(std::ostream& stream,
+ std::string const& style, int size,
+ Range1 const& range, TransformStrategy const& strategy)
+ {
+ Range2 irange;
+ geometry::transform(range, irange, strategy);
+ stream << geometry::svg(irange, style, size) << std::endl;
+ }
+};
+
+template <typename Segment>
+struct svg_map<segment_tag, Segment>
+{
+ template <typename TransformStrategy>
+ static inline void apply(std::ostream& stream,
+ std::string const& style, int size,
+ Segment const& segment, TransformStrategy const& strategy)
+ {
+ typedef segment_view<Segment> view_type;
+ view_type range(segment);
+ svg_map_range
+ <
+ view_type,
+ model::linestring<detail::svg::svg_point_type>
+ >::apply(stream, style, size, range, strategy);
+ }
+};
+
+
+template <typename Ring>
+struct svg_map<ring_tag, Ring>
+ : svg_map_range<Ring, model::ring<detail::svg::svg_point_type> >
+{};
+
+
+template <typename Linestring>
+struct svg_map<linestring_tag, Linestring>
+ : svg_map_range<Linestring, model::linestring<detail::svg::svg_point_type> >
+{};
+
+
+template <typename Polygon>
+struct svg_map<polygon_tag, Polygon>
+{
+ template <typename TransformStrategy>
+ static inline void apply(std::ostream& stream,
+ std::string const& style, int size,
+ Polygon const& polygon, TransformStrategy const& strategy)
+ {
+ model::polygon<detail::svg::svg_point_type> ipoly;
+ geometry::transform(polygon, ipoly, strategy);
+ stream << geometry::svg(ipoly, style, size) << std::endl;
+ }
+};
+
+
+template <typename Multi>
+struct svg_map<multi_tag, Multi>
+{
+ typedef typename single_tag_of
+ <
+ typename geometry::tag<Multi>::type
+ >::type stag;
+
+ template <typename TransformStrategy>
+ static inline void apply(std::ostream& stream,
+ std::string const& style, int size,
+ Multi const& multi, TransformStrategy const& strategy)
+ {
+ for (typename boost::range_iterator<Multi const>::type it
+ = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ svg_map
+ <
+ stag,
+ typename boost::range_value<Multi>::type
+ >::apply(stream, style, size, *it, strategy);
+ }
+ }
+};
+
+
+} // namespace dispatch
+#endif
+
+
+template <typename Geometry, typename TransformStrategy>
+inline void svg_map(std::ostream& stream,
+ std::string const& style, int size,
+ Geometry const& geometry, TransformStrategy const& strategy)
+{
+ dispatch::svg_map
+ <
+ typename tag_cast
+ <
+ typename tag<Geometry>::type,
+ multi_tag
+ >::type,
+ typename boost::remove_const<Geometry>::type
+ >::apply(stream, style, size, geometry, strategy);
+}
+
+
+template <typename Point, bool SameScale = true>
+class svg_mapper : boost::noncopyable
+{
+ typedef strategy::transform::map_transformer
+ <
+ Point,
+ detail::svg::svg_point_type,
+ true,
+ SameScale
+ > transformer_type;
+
+ model::box<Point> m_bounding_box;
+ boost::scoped_ptr<transformer_type> m_matrix;
+ std::ostream& m_stream;
+ int m_width, m_height;
+ std::string m_width_height; // for <svg> tag only, defaults to 2x 100%
+
+ void init_matrix()
+ {
+ if (! m_matrix)
+ {
+ m_matrix.reset(new transformer_type(m_bounding_box,
+ m_width, m_height));
+
+ m_stream << "<?xml version=\"1.0\" standalone=\"no\"?>"
+ << std::endl
+ << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\""
+ << std::endl
+ << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
+ << std::endl
+ << "<svg " << m_width_height << " version=\"1.1\""
+ << std::endl
+ << "xmlns=\"http://www.w3.org/2000/svg\">"
+ << std::endl;
+ }
+ }
+
+public :
+ svg_mapper(std::ostream& s, int w, int h
+ , std::string const& width_height = "width=\"100%\" height=\"100%\"")
+ : m_stream(s)
+ , m_width(w)
+ , m_height(h)
+ , m_width_height(width_height)
+ {
+ assign_inverse(m_bounding_box);
+ }
+
+ virtual ~svg_mapper()
+ {
+ m_stream << "</svg>" << std::endl;
+ }
+
+ template <typename Geometry>
+ void add(Geometry const& geometry)
+ {
+ if (num_points(geometry) > 0)
+ {
+ expand(m_bounding_box,
+ return_envelope
+ <
+ model::box<Point>
+ >(geometry));
+ }
+ }
+
+ template <typename Geometry>
+ void map(Geometry const& geometry, std::string const& style,
+ int size = -1)
+ {
+ BOOST_MPL_ASSERT_MSG
+ (
+ ( boost::is_same
+ <
+ Point,
+ typename point_type<Geometry>::type
+ >::value )
+ , POINT_TYPES_ARE_NOT_SAME_FOR_MAPPER_AND_MAP
+ , (types<Point, typename point_type<Geometry>::type>)
+ );
+
+
+ init_matrix();
+ svg_map(m_stream, style, size, geometry, *m_matrix);
+ }
+
+ template <typename TextPoint>
+ void text(TextPoint const& point, std::string const& s,
+ std::string const& style,
+ int offset_x = 0, int offset_y = 0, int lineheight = 10)
+ {
+ init_matrix();
+ detail::svg::svg_point_type map_point;
+ transform(point, map_point, *m_matrix);
+ m_stream
+ << "<text style=\"" << style << "\""
+ << " x=\"" << get<0>(map_point) + offset_x << "\""
+ << " y=\"" << get<1>(map_point) + offset_y << "\""
+ << ">";
+ if (s.find("\n") == std::string::npos)
+ {
+ m_stream << s;
+ }
+ else
+ {
+ // Multi-line modus
+
+ std::vector<std::string> splitted;
+ boost::split(splitted, s, boost::is_any_of("\n"));
+ for (std::vector<std::string>::const_iterator it
+ = splitted.begin();
+ it != splitted.end();
+ ++it, offset_y += lineheight)
+ {
+ m_stream
+ << "<tspan x=\"" << get<0>(map_point) + offset_x
+ << "\""
+ << " y=\"" << get<1>(map_point) + offset_y
+ << "\""
+ << ">" << *it << "</tspan>";
+ }
+ }
+ m_stream << "</text>" << std::endl;
+ }
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_IO_SVG_MAPPER_HPP
diff --git a/src/boost/geometry/extensions/io/svg/write_svg.hpp b/src/boost/geometry/extensions/io/svg/write_svg.hpp
new file mode 100644
index 0000000..3cc2cda
--- /dev/null
+++ b/src/boost/geometry/extensions/io/svg/write_svg.hpp
@@ -0,0 +1,272 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_SVG_WRITE_SVG_HPP
+#define BOOST_GEOMETRY_IO_SVG_WRITE_SVG_HPP
+
+#include <ostream>
+#include <string>
+
+#include <boost/config.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace svg
+{
+
+
+template <typename Point>
+struct svg_point
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Point const& p, std::string const& style, int size)
+ {
+ os << "<circle cx=\"" << geometry::get<0>(p)
+ << "\" cy=\"" << geometry::get<1>(p)
+ << "\" r=\"" << (size < 0 ? 5 : size)
+ << "\" style=\"" << style << "\"/>";
+ }
+};
+
+
+template <typename Box>
+struct svg_box
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Box const& box, std::string const& style, int size)
+ {
+ // Prevent invisible boxes, making them >=1, using "max"
+ BOOST_USING_STD_MAX();
+
+ typedef typename coordinate_type<Box>::type ct;
+ ct x = geometry::get<geometry::min_corner, 0>(box);
+ ct y = geometry::get<geometry::min_corner, 1>(box);
+ ct width = max BOOST_PREVENT_MACRO_SUBSTITUTION(1,
+ geometry::get<geometry::max_corner, 0>(box) - x);
+ ct height = max BOOST_PREVENT_MACRO_SUBSTITUTION (1,
+ geometry::get<geometry::max_corner, 1>(box) - y);
+
+ os << "<rect x=\"" << x << "\" y=\"" << y
+ << "\" width=\"" << width << "\" height=\"" << height
+ << "\" style=\"" << style << "\"/>";
+ }
+};
+
+
+/*!
+\brief Stream ranges as SVG
+\note policy is used to select type (polyline/polygon)
+*/
+template <typename Range, typename Policy>
+struct svg_range
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Range const& range, std::string const& style, int size)
+ {
+ typedef typename boost::range_iterator<Range const>::type iterator;
+
+ bool first = true;
+
+ os << "<" << Policy::prefix() << " points=\"";
+
+ for (iterator it = boost::begin(range);
+ it != boost::end(range);
+ ++it, first = false)
+ {
+ os << (first ? "" : " " )
+ << geometry::get<0>(*it)
+ << ","
+ << geometry::get<1>(*it);
+ }
+ os << "\" style=\"" << style << Policy::style() << "\"/>";
+ }
+};
+
+
+
+template <typename Polygon>
+struct svg_poly
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Polygon const& polygon, std::string const& style, int size)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+ typedef typename boost::range_iterator<ring_type const>::type iterator_type;
+
+ bool first = true;
+ os << "<g fill-rule=\"evenodd\"><path d=\"";
+
+ ring_type const& ring = geometry::exterior_ring(polygon);
+ for (iterator_type it = boost::begin(ring);
+ it != boost::end(ring);
+ ++it, first = false)
+ {
+ os << (first ? "M" : " L") << " "
+ << geometry::get<0>(*it)
+ << ","
+ << geometry::get<1>(*it);
+ }
+
+ // Inner rings:
+ {
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO_TPL(rit, boost::begin(rings));
+ rit != boost::end(rings); ++rit)
+ {
+ first = true;
+ for (BOOST_AUTO_TPL(it, boost::begin(*rit)); it != boost::end(*rit);
+ ++it, first = false)
+ {
+ os << (first ? "M" : " L") << " "
+ << geometry::get<0>(*it)
+ << ","
+ << geometry::get<1>(*it);
+ }
+ }
+ }
+ os << " z \" style=\"" << style << "\"/></g>";
+
+ }
+};
+
+
+
+struct prefix_linestring
+{
+ static inline const char* prefix() { return "polyline"; }
+ static inline const char* style() { return ";fill:none"; }
+};
+
+
+struct prefix_ring
+{
+ static inline const char* prefix() { return "polygon"; }
+ static inline const char* style() { return ""; }
+};
+
+
+
+}} // namespace detail::svg
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+/*!
+\brief Dispatching base struct for SVG streaming, specialized below per geometry type
+\details Specializations should implement a static method "stream" to stream a geometry
+The static method should have the signature:
+
+template <typename Char, typename Traits>
+static inline void apply(std::basic_ostream<Char, Traits>& os, G const& geometry)
+*/
+template <typename GeometryTag, typename Geometry>
+struct svg
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (Geometry)
+ );
+};
+
+template <typename Point>
+struct svg<point_tag, Point> : detail::svg::svg_point<Point> {};
+
+template <typename Box>
+struct svg<box_tag, Box> : detail::svg::svg_box<Box> {};
+
+template <typename Linestring>
+struct svg<linestring_tag, Linestring>
+ : detail::svg::svg_range<Linestring, detail::svg::prefix_linestring> {};
+
+template <typename Ring>
+struct svg<ring_tag, Ring>
+ : detail::svg::svg_range<Ring, detail::svg::prefix_ring> {};
+
+template <typename Polygon>
+struct svg<polygon_tag, Polygon>
+ : detail::svg::svg_poly<Polygon> {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup svg
+\details Stream manipulator, streams geometry classes as Virtual Earth shape
+*/
+template <typename G>
+class svg_manipulator
+{
+public:
+
+ inline svg_manipulator(G const& g, std::string const& style, int size)
+ : m_geometry(g)
+ , m_style(style)
+ , m_size(size)
+ {}
+
+ template <typename Char, typename Traits>
+ inline friend std::basic_ostream<Char, Traits>& operator<<(
+ std::basic_ostream<Char, Traits>& os, svg_manipulator const& m)
+ {
+ dispatch::svg
+ <
+ typename tag<G>::type, G
+ >::apply(os, m.m_geometry, m.m_style, m.m_size);
+ os.flush();
+ return os;
+ }
+
+private:
+ G const& m_geometry;
+ std::string const& m_style;
+ int m_size;
+};
+
+/*!
+\brief Main svg function to stream geometries as SVG
+\ingroup svg
+*/
+template <typename Geometry>
+inline svg_manipulator<Geometry> svg(Geometry const& t, std::string const& style, int size = -1)
+{
+ concept::check<Geometry const>();
+
+ return svg_manipulator<Geometry>(t, style, size);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_SVG_WRITE_SVG_HPP
diff --git a/src/boost/geometry/extensions/io/svg/write_svg_multi.hpp b/src/boost/geometry/extensions/io/svg/write_svg_multi.hpp
new file mode 100644
index 0000000..3ca2c62
--- /dev/null
+++ b/src/boost/geometry/extensions/io/svg/write_svg_multi.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_SVG_WRITE_SVG_MULTI_HPP
+#define BOOST_GEOMETRY_IO_SVG_WRITE_SVG_MULTI_HPP
+
+
+#include <boost/geometry/extensions/io/svg/write_svg.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace svg
+{
+
+
+template <typename MultiGeometry, typename Policy>
+struct svg_multi
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ MultiGeometry const& multi, std::string const& style, int size)
+ {
+ for (typename boost::range_iterator<MultiGeometry const>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ Policy::apply(os, *it, style, size);
+ }
+
+ }
+
+};
+
+
+
+}} // namespace detail::svg
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon>
+struct svg<multi_polygon_tag, MultiPolygon>
+ : detail::svg::svg_multi
+ <
+ MultiPolygon,
+ detail::svg::svg_poly
+ <
+ typename boost::range_value<MultiPolygon>::type
+ >
+
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_IO_SVG_WRITE_SVG_MULTI_HPP
diff --git a/src/boost/geometry/extensions/iterators/circular_iterator.hpp b/src/boost/geometry/extensions/iterators/circular_iterator.hpp
new file mode 100644
index 0000000..31ae5ce
--- /dev/null
+++ b/src/boost/geometry/extensions/iterators/circular_iterator.hpp
@@ -0,0 +1,121 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ITERATORS_CIRCULAR_ITERATOR_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ITERATORS_CIRCULAR_ITERATOR_HPP
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <boost/geometry/iterators/base.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+ \brief Iterator which goes circular through a range, starting at a point, ending at that point
+ \tparam Iterator iterator on which this class is based on
+ \ingroup iterators
+*/
+template <typename Iterator>
+struct circular_iterator :
+ public detail::iterators::iterator_base
+ <
+ circular_iterator<Iterator>,
+ Iterator
+ >
+{
+ friend class boost::iterator_core_access;
+
+ explicit inline circular_iterator(Iterator begin, Iterator end, Iterator start)
+ : m_begin(begin)
+ , m_end(end)
+ , m_start(start)
+ {
+ this->base_reference() = start;
+ }
+
+ // Constructor to indicate the end of a range, to enable e.g. std::copy
+ explicit inline circular_iterator(Iterator end)
+ : m_begin(end)
+ , m_end(end)
+ , m_start(end)
+ {
+ this->base_reference() = end;
+ }
+
+ /// Navigate to a certain position, should be in [start .. end], it at end
+ /// it will circle again.
+ inline void moveto(Iterator it)
+ {
+ this->base_reference() = it;
+ check_end();
+ }
+
+private:
+
+ inline void increment()
+ {
+ if (this->base() != m_end)
+ {
+ (this->base_reference())++;
+ check_end();
+ }
+ }
+ inline void decrement()
+ {
+ if (this->base() != m_end)
+ {
+ // If at begin, go back to end (assumed this is possible...)
+ if (this->base() == m_begin)
+ {
+ this->base_reference() = this->m_end;
+ }
+
+ // Decrement
+ (this->base_reference())--;
+
+ // If really back at start, go to end == end of iteration
+ if (this->base() == m_start)
+ {
+ this->base_reference() = this->m_end;
+ }
+ }
+ }
+
+
+ inline void check_end()
+ {
+ if (this->base() == this->m_end)
+ {
+ this->base_reference() = this->m_begin;
+ }
+
+ if (this->base() == m_start)
+ {
+ this->base_reference() = this->m_end;
+ }
+ }
+
+ Iterator m_begin;
+ Iterator m_end;
+ Iterator m_start;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ITERATORS_CIRCULAR_ITERATOR_HPP
diff --git a/src/boost/geometry/extensions/iterators/section_iterators.hpp b/src/boost/geometry/extensions/iterators/section_iterators.hpp
new file mode 100644
index 0000000..d0751f6
--- /dev/null
+++ b/src/boost/geometry/extensions/iterators/section_iterators.hpp
@@ -0,0 +1,233 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ITERATORS_SECTION_ITERATORS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ITERATORS_SECTION_ITERATORS_HPP
+
+// 24-04-2010, Moved to extensions/iterators
+// because it was not yet used in the part.
+
+// FILE WILL BE SPLITTED
+
+
+#include <iterator>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/iterators/base.hpp>
+#include <boost/geometry/algorithms/overlaps.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace detail
+{
+
+ template <size_t D, typename P, typename B>
+ inline bool exceeding(short int dir, P const& point, B const& box)
+ {
+ return (dir == 1 && get<D>(point) > get<1, D>(box))
+ || (dir == -1 && get<D>(point) < get<0, D>(box));
+ }
+
+ template <size_t D, typename P, typename B>
+ inline bool preceding(short int dir, P const& point, B const& box)
+ {
+ return (dir == 1 && get<D>(point) < get<0, D>(box))
+ || (dir == -1 && get<D>(point) > get<1, D>(box));
+ }
+}
+
+
+// Iterator walking through ring/sections, delivering only those points of the ring
+// which are inside the specified box (using the sections)
+template<typename G, typename S, typename B, size_t D>
+struct section_iterator : public detail::iterators::iterator_base<
+ section_iterator<G, S, B, D>,
+ typename boost::range_iterator<G const>::type
+ >
+{
+ friend class boost::iterator_core_access;
+
+ inline section_iterator(G const& ring, S const& sections, B const& box)
+ : m_ring(ring)
+ , m_sections(sections)
+ , m_box(box)
+ , m_section_iterator(boost::begin(m_sections))
+ {
+ stay_within_box();
+ }
+
+
+private :
+
+ inline void increment()
+ {
+ (this->base_reference())++;
+
+ // If end or exceeding specified box, go to next section
+ if (this->base() == m_end
+ || detail::exceeding<D>(m_section_iterator->directions[0], *this->base(), m_box))
+ {
+ m_section_iterator++;
+ stay_within_box();
+ }
+
+ }
+
+ // Check if iterator is still in box and if not, go to the next section and advance until it is in box
+ void stay_within_box()
+ {
+ // Find section having overlap with specified box
+ while (m_section_iterator != boost::end(m_sections)
+ && ! overlaps(m_section_iterator->bounding_box, m_box))
+ {
+ m_section_iterator++;
+ }
+ if (m_section_iterator != boost::end(m_sections))
+ {
+ this->base_reference() = boost::begin(m_ring) + m_section_iterator->begin_index;
+ m_end = boost::begin(m_ring) + m_section_iterator->end_index + 1;
+
+ // While not yet at box, advance
+ while(this->base() != m_end
+ && detail::preceding<D>(m_section_iterator->directions[0], *this->base(), m_box))
+ {
+ ++(this->base_reference());
+ }
+
+ if (this->base() == m_end)
+ {
+ // This should actually not occur because of bbox check, but to be sure
+ m_section_iterator++;
+ stay_within_box();
+ }
+ }
+ else
+ {
+ this->base_reference() = boost::end(m_ring);
+ m_end = boost::end(m_ring);
+ }
+ }
+
+
+ typedef typename boost::range_iterator<G const>::type IT;
+ typedef typename boost::range_iterator<S const>::type SIT;
+
+ G const& m_ring;
+ S const& m_sections;
+ B const& m_box;
+
+ IT m_end;
+ SIT m_section_iterator;
+};
+
+
+// Iterator walking through ring/sections, delivering only those points of the ring
+// which are inside the specified box (using the sections)
+template<typename G, typename SEC, typename B, size_t D>
+struct one_section_segment_iterator : public detail::iterators::iterator_base<
+ one_section_segment_iterator<G, SEC, B, D>
+ , typename boost::range_iterator<G const>::type>
+{
+ friend class boost::iterator_core_access;
+ typedef typename boost::range_iterator<G const>::type normal_iterator;
+
+ inline one_section_segment_iterator(G const& ring, SEC const& section, B const& box)
+ : m_box(&box)
+ , m_dir(section.directions[0])
+ {
+ init(section, ring);
+ }
+
+ inline one_section_segment_iterator(normal_iterator end)
+ : m_section_end(end)
+ , m_ring_end(end)
+ , m_box(NULL)
+ , m_dir(0)
+ {
+ this->base_reference() = end;
+ }
+
+
+private :
+
+ inline void increment()
+ {
+ m_previous = (this->base_reference())++;
+
+ if (this->base() == m_section_end
+ || detail::exceeding<D>(m_dir, *m_previous, *m_box))
+ {
+ this->base_reference() = m_ring_end;
+ }
+ }
+
+ // Check if iterator is still in box and if not, go to the next section and advance until it is in box
+ void init(SEC const& section, G const& ring)
+ {
+ //this->base_reference();
+ m_section_end = boost::begin(ring) + section.end_index + 1;
+ m_ring_end = boost::end(ring);
+
+ this->base_reference() = boost::begin(ring) + section.begin_index;
+
+ /* Performance, TO BE CHECKED!
+ normal_iterator next = boost::begin(ring) + section.begin_index;
+ if (next != m_section_end && next != m_ring_end)
+ {
+
+ // While (not end and) not yet at box, advance
+ normal_iterator it = next++;
+ while(next != m_section_end && next != m_ring_end
+ && detail::preceding<D>(m_dir, *next, *m_box))
+ {
+ it = next++;
+ }
+
+
+ if (it == m_section_end)
+ {
+ this->base_reference() = m_ring_end;
+ }
+ else
+ {
+ this->base_reference() = it;
+ }
+ }
+ else
+ {
+ this->base_reference() = m_ring_end;
+ }
+ */
+
+ m_previous = this->base();
+ }
+
+
+ const B* m_box;
+ short int m_dir;
+
+ normal_iterator m_previous;
+ normal_iterator m_section_end;
+ normal_iterator m_ring_end;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ITERATORS_SECTION_ITERATORS_HPP
diff --git a/src/boost/geometry/extensions/iterators/segment_returning_iterator.hpp b/src/boost/geometry/extensions/iterators/segment_returning_iterator.hpp
new file mode 100644
index 0000000..c92df37
--- /dev/null
+++ b/src/boost/geometry/extensions/iterators/segment_returning_iterator.hpp
@@ -0,0 +1,139 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ITERATORS_SEGMENT_RETURNING_ITERATOR_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ITERATORS_SEGMENT_RETURNING_ITERATOR_HPP
+
+// TODO: This is very experimental version of input iterator
+// reading collection of points as segments - proof of concept.
+// --mloskot
+
+// TODO: Move to boost::iterator_adaptor
+
+#include <iterator>
+
+#include <boost/assert.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <boost/geometry/algorithms/equals.hpp>
+
+// Helper geometry
+#include <boost/geometry/geometries/segment.hpp>
+
+namespace boost { namespace geometry
+{
+
+template <typename Base, typename Point>
+struct segment_returning_iterator
+{
+ typedef Base base_type;
+ typedef Point point_type;
+ typedef typename model::referring_segment<Point> segment_type;
+
+ typedef std::input_iterator_tag iterator_category;
+ typedef typename std::iterator_traits<Base>::difference_type difference_type;
+ typedef segment_type value_type;
+ typedef segment_type* pointer;
+ typedef segment_type& reference;
+
+ explicit segment_returning_iterator(Base const& end)
+ : m_segment(p1 , p2)
+ , m_prev(end)
+ , m_it(end)
+ , m_end(end)
+ {
+ }
+
+ segment_returning_iterator(Base const& it, Base const& end)
+ : m_segment(p1 , p2)
+ , m_prev(it)
+ , m_it(it)
+ , m_end(end)
+ {
+ if (m_it != m_end)
+ {
+ BOOST_ASSERT(m_prev != m_end);
+ ++m_it;
+ }
+ }
+
+ reference operator*()
+ {
+ BOOST_ASSERT(m_it != m_end && m_prev != m_end);
+
+ p1 = *m_prev;
+ p2 = *m_it;
+
+ return m_segment;
+ }
+
+ pointer operator->()
+ {
+ return &(operator*());
+ }
+
+ segment_returning_iterator& operator++()
+ {
+ ++m_prev;
+ ++m_it;
+ return *this;
+ }
+
+ segment_returning_iterator operator++(int)
+ {
+ segment_returning_iterator it(*this);
+ ++(*this);
+ return it;
+ }
+
+ Base const& base() const { return m_it; }
+
+private:
+
+ point_type p1;
+ point_type p2;
+ segment_type m_segment;
+
+ Base m_prev;
+ Base m_it;
+ Base m_end;
+};
+
+template <typename Base, typename Point>
+bool operator==(segment_returning_iterator<Base, Point> const& lhs,
+ segment_returning_iterator<Base, Point> const& rhs)
+{
+ return (lhs.base() == rhs.base());
+}
+
+template <typename Base, typename Point>
+bool operator!=(segment_returning_iterator<Base, Point> const& lhs,
+ segment_returning_iterator<Base, Point> const& rhs)
+{
+ return (lhs.base() != rhs.base());
+}
+
+template <typename C>
+inline segment_returning_iterator
+<
+ typename C::iterator,
+ typename C::value_type
+>
+make_segment_returning_iterator(C& c)
+{
+ typedef typename C::iterator base_iterator;
+ typedef typename C::value_type point_type;
+ return segment_returning_iterator<base_iterator, point_type>(c.begin(), c.end());
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ITERATORS_SEGMENT_RETURNING_ITERATOR_HPP
diff --git a/src/boost/geometry/extensions/multi/algorithms/dissolve.hpp b/src/boost/geometry/extensions/multi/algorithms/dissolve.hpp
new file mode 100644
index 0000000..a6f5d60
--- /dev/null
+++ b/src/boost/geometry/extensions/multi/algorithms/dissolve.hpp
@@ -0,0 +1,99 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_MULTI_ALGORITHMS_DISSOLVE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_MULTI_ALGORITHMS_DISSOLVE_HPP
+
+
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+
+#include <boost/geometry/algorithms/union.hpp>
+
+#include <boost/geometry/extensions/algorithms/dissolve.hpp>
+#include <boost/geometry/extensions/algorithms/detail/overlay/dissolver.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dissolve
+{
+
+template <typename Multi, typename GeometryOut>
+struct dissolve_multi
+{
+ template <typename OutputIterator>
+ static inline OutputIterator apply(Multi const& multi, OutputIterator out)
+ {
+ typedef typename boost::range_value<Multi>::type polygon_type;
+ typedef typename boost::range_iterator<Multi const>::type iterator_type;
+
+ // Step 1: dissolve all polygons in the multi-polygon, independantly
+ std::vector<GeometryOut> step1;
+ for (iterator_type it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ dissolve_ring_or_polygon
+ <
+ polygon_type,
+ GeometryOut
+ >::apply(*it, std::back_inserter(step1));
+ }
+
+ // Step 2: remove mutual overlap
+ {
+ std::vector<GeometryOut> step2; // TODO avoid this, output to "out", if possible
+ detail::dissolver::dissolver_generic<detail::dissolver::plusmin_policy>::apply(step1, step2);
+ for (typename std::vector<GeometryOut>::const_iterator it = step2.begin();
+ it != step2.end(); ++it)
+ {
+ *out++ = *it;
+ }
+ }
+
+ return out;
+ }
+};
+
+// Dissolving multi-linestring is currently moved to extensions/algorithms/connect,
+// because it is actually different from dissolving of polygons.
+// To be decided what the final behaviour/name is.
+
+}} // namespace detail::dissolve
+#endif
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template<typename Multi, typename GeometryOut>
+struct dissolve<multi_polygon_tag, polygon_tag, Multi, GeometryOut>
+ : detail::dissolve::dissolve_multi<Multi, GeometryOut>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_MULTI_ALGORITHMS_DISSOLVE_HPP
diff --git a/src/boost/geometry/extensions/nsphere/algorithms/append.hpp b/src/boost/geometry/extensions/nsphere/algorithms/append.hpp
new file mode 100644
index 0000000..3a271b2
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/algorithms/append.hpp
@@ -0,0 +1,45 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_APPEND_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_APPEND_HPP
+
+
+#include <boost/geometry/algorithms/append.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// This file is probably obsolete
+
+//template <typename TagRoP, typename N, typename RoP, bool Std>
+//struct append<nsphere_tag, TagRoP, N, RoP, Std> {};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_APPEND_HPP
diff --git a/src/boost/geometry/extensions/nsphere/algorithms/area.hpp b/src/boost/geometry/extensions/nsphere/algorithms/area.hpp
new file mode 100644
index 0000000..f3fce16
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/algorithms/area.hpp
@@ -0,0 +1,82 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_AREA_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_AREA_HPP
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace area
+{
+
+template<typename C, typename S>
+struct circle_area
+{
+ typedef typename coordinate_type<C>::type coordinate_type;
+
+ // Returning the coordinate precision, but if integer, returning a double
+ typedef typename boost::mpl::if_c
+ <
+ boost::is_integral<coordinate_type>::type::value,
+ double,
+ coordinate_type
+ >::type return_type;
+
+ static inline return_type apply(C const& c, S const&)
+ {
+ // Currently only works for Cartesian circles
+ // Todo: use strategy
+ // Todo: use concept
+ assert_dimension<C, 2>();
+
+ return_type r = get_radius<0>(c);
+ r *= r * boost::math::constants::pi<return_type>();
+ return r;
+ }
+};
+
+
+
+}} // namespace detail::area
+
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry, typename Strategy>
+struct area<nsphere_tag, Geometry, Strategy>
+ : detail::area::circle_area<Geometry, Strategy>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_AREA_HPP
diff --git a/src/boost/geometry/extensions/nsphere/algorithms/assign.hpp b/src/boost/geometry/extensions/nsphere/algorithms/assign.hpp
new file mode 100644
index 0000000..0d83fa6
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/algorithms/assign.hpp
@@ -0,0 +1,93 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_ASSIGN_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_ASSIGN_HPP
+
+#include <boost/geometry/algorithms/assign.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+#include <boost/geometry/extensions/nsphere/core/radius.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename S>
+struct assign<nsphere_tag, S, 2>
+{
+ typedef typename coordinate_type<S>::type coordinate_type;
+ typedef typename radius_type<S>::type radius_type;
+
+ /// 2-value version for an n-sphere is valid for circle and sets the center
+ template <typename T>
+ static inline void apply(S& sphercle, T const& c1, T const& c2)
+ {
+ set<0>(sphercle, boost::numeric_cast<coordinate_type>(c1));
+ set<1>(sphercle, boost::numeric_cast<coordinate_type>(c2));
+ }
+
+ template <typename T, typename R>
+ static inline void apply(S& sphercle, T const& c1,
+ T const& c2, R const& radius)
+ {
+ set<0>(sphercle, boost::numeric_cast<coordinate_type>(c1));
+ set<1>(sphercle, boost::numeric_cast<coordinate_type>(c2));
+ set_radius<0>(sphercle, boost::numeric_cast<radius_type>(radius));
+ }
+};
+
+template <typename S>
+struct assign<nsphere_tag, S, 3>
+{
+ typedef typename coordinate_type<S>::type coordinate_type;
+ typedef typename radius_type<S>::type radius_type;
+
+ /// 4-value version for an n-sphere is valid for a sphere and sets the center and the radius
+ template <typename T>
+ static inline void apply(S& sphercle, T const& c1, T const& c2, T const& c3)
+ {
+ set<0>(sphercle, boost::numeric_cast<coordinate_type>(c1));
+ set<1>(sphercle, boost::numeric_cast<coordinate_type>(c2));
+ set<2>(sphercle, boost::numeric_cast<coordinate_type>(c3));
+ }
+
+ /// 4-value version for an n-sphere is valid for a sphere and sets the center and the radius
+ template <typename T, typename R>
+ static inline void apply(S& sphercle, T const& c1,
+ T const& c2, T const& c3, R const& radius)
+ {
+
+ set<0>(sphercle, boost::numeric_cast<coordinate_type>(c1));
+ set<1>(sphercle, boost::numeric_cast<coordinate_type>(c2));
+ set<2>(sphercle, boost::numeric_cast<coordinate_type>(c3));
+ set_radius<0>(sphercle, boost::numeric_cast<radius_type>(radius));
+ }
+
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_ASSIGN_HPP
diff --git a/src/boost/geometry/extensions/nsphere/algorithms/clear.hpp b/src/boost/geometry/extensions/nsphere/algorithms/clear.hpp
new file mode 100644
index 0000000..c59f7e8
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/algorithms/clear.hpp
@@ -0,0 +1,47 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_CLEAR_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_CLEAR_HPP
+
+
+#include <boost/geometry/algorithms/clear.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+
+template <typename Geometry>
+struct clear<nsphere_tag, Geometry>
+ : detail::clear::no_action<Geometry>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_CLEAR_HPP
diff --git a/src/boost/geometry/extensions/nsphere/algorithms/envelope.hpp b/src/boost/geometry/extensions/nsphere/algorithms/envelope.hpp
new file mode 100644
index 0000000..f265f16
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/algorithms/envelope.hpp
@@ -0,0 +1,83 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_ENVELOPE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_ENVELOPE_HPP
+
+
+#include <boost/geometry/algorithms/envelope.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope
+{
+
+/// Calculate envelope of an n-sphere, circle or sphere (currently only for Cartesian 2D points)
+template<typename Box, typename Nsphere, typename Strategy>
+struct envelope_nsphere
+{
+ static inline void apply(Nsphere const& nsphere, Box& mbr, Strategy const&)
+ {
+ assert_dimension<Nsphere, 2>();
+ assert_dimension<Box, 2>();
+
+ typename radius_type<Nsphere>::type radius = get_radius<0>(nsphere);
+ set<min_corner, 0>(mbr, get<0>(nsphere) - radius);
+ set<min_corner, 1>(mbr, get<1>(nsphere) - radius);
+ set<max_corner, 0>(mbr, get<0>(nsphere) + radius);
+ set<max_corner, 1>(mbr, get<1>(nsphere) + radius);
+ }
+};
+
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename Nsphere,
+ typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+ <
+ nsphere_tag, box_tag,
+ Nsphere, Box,
+ StrategyLess, StrategyGreater
+ >
+ : detail::envelope::envelope_nsphere
+ <
+ Nsphere, Box,
+ StrategyLess
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_ENVELOPE_HPP
diff --git a/src/boost/geometry/extensions/nsphere/algorithms/num_points.hpp b/src/boost/geometry/extensions/nsphere/algorithms/num_points.hpp
new file mode 100644
index 0000000..5525bfd
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/algorithms/num_points.hpp
@@ -0,0 +1,46 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_NUM_POINTS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_NUM_POINTS_HPP
+
+#include <boost/geometry/algorithms/num_points.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry>
+struct num_points<nsphere_tag, false, Geometry>
+ : detail::num_points::other_count<Geometry, 1>
+{};
+
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_NUM_POINTS_HPP
diff --git a/src/boost/geometry/extensions/nsphere/algorithms/within.hpp b/src/boost/geometry/extensions/nsphere/algorithms/within.hpp
new file mode 100644
index 0000000..088548e
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/algorithms/within.hpp
@@ -0,0 +1,209 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_WITHIN_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_WITHIN_HPP
+
+
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/make.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/access.hpp>
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/assign.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within
+{
+
+
+
+//-------------------------------------------------------------------------------------------------------
+// Implementation for n-spheres. Supports circles or spheres, in 2 or 3 dimensions, in Euclidian system
+// Circle center might be of other point-type as geometry
+// Todo: implement as strategy
+//-------------------------------------------------------------------------------------------------------
+template<typename P, typename C>
+inline bool point_in_circle(P const& p, C const& c)
+{
+ namespace services = strategy::distance::services;
+
+ assert_dimension<C, 2>();
+
+ typedef typename point_type<C>::type point_type;
+ typedef typename services::default_strategy
+ <
+ point_tag, P, point_type
+ >::type strategy_type;
+ typedef typename services::return_type<strategy_type>::type return_type;
+
+ strategy_type strategy;
+
+ P const center = geometry::make<P>(get<0>(c), get<1>(c));
+ return_type const r = geometry::distance(p, center, strategy);
+ return_type const rad = services::result_from_distance
+ <
+ strategy_type
+ >::apply(strategy, get_radius<0>(c));
+
+ return r < rad;
+}
+/// 2D version
+template<typename T, typename C>
+inline bool point_in_circle(T const& c1, T const& c2, C const& c)
+{
+ typedef typename point_type<C>::type point_type;
+
+ point_type p = geometry::make<point_type>(c1, c2);
+ return point_in_circle(p, c);
+}
+
+template<typename B, typename C>
+inline bool box_in_circle(B const& b, C const& c)
+{
+ typedef typename point_type<B>::type point_type;
+
+ // Currently only implemented for 2d geometries
+ assert_dimension<point_type, 2>();
+ assert_dimension<C, 2>();
+
+ // Box: all four points must lie within circle
+
+ // Check points lower-left and upper-right, then lower-right and upper-left
+ return point_in_circle(get<min_corner, 0>(b), get<min_corner, 1>(b), c)
+ && point_in_circle(get<max_corner, 0>(b), get<max_corner, 1>(b), c)
+ && point_in_circle(get<min_corner, 0>(b), get<max_corner, 1>(b), c)
+ && point_in_circle(get<max_corner, 0>(b), get<min_corner, 1>(b), c);
+}
+
+// Generic "range-in-circle", true if all points within circle
+template<typename R, typename C>
+inline bool range_in_circle(R const& range, C const& c)
+{
+ assert_dimension<R, 2>();
+ assert_dimension<C, 2>();
+
+ for (typename boost::range_iterator<R const>::type it = boost::begin(range);
+ it != boost::end(range); ++it)
+ {
+ if (! point_in_circle(*it, c))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+template<typename Y, typename C>
+inline bool polygon_in_circle(Y const& poly, C const& c)
+{
+ return range_in_circle(exterior_ring(poly), c);
+}
+
+
+
+template<typename I, typename C>
+inline bool multi_polygon_in_circle(I const& m, C const& c)
+{
+ for (typename I::const_iterator i = m.begin(); i != m.end(); i++)
+ {
+ if (! polygon_in_circle(*i, c))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename P, typename Circle, typename Strategy>
+struct within<point_tag, nsphere_tag, P, Circle, Strategy>
+{
+ static inline bool apply(P const& p, Circle const& c, Strategy const&)
+ {
+ return detail::within::point_in_circle(p, c);
+ }
+};
+
+template <typename Box, typename Circle, typename Strategy>
+struct within<box_tag, nsphere_tag, Box, Circle, Strategy>
+{
+ static inline bool apply(Box const& b, Circle const& c, Strategy const&)
+ {
+ return detail::within::box_in_circle(b, c);
+ }
+};
+
+template <typename Linestring, typename Circle, typename Strategy>
+struct within<linestring_tag, nsphere_tag, Linestring, Circle, Strategy>
+{
+ static inline bool apply(Linestring const& ln, Circle const& c, Strategy const&)
+ {
+ return detail::within::range_in_circle(ln, c);
+ }
+};
+
+template <typename Ring, typename Circle, typename Strategy>
+struct within<ring_tag, nsphere_tag, Ring, Circle, Strategy>
+{
+ static inline bool apply(Ring const& r, Circle const& c, Strategy const&)
+ {
+ return detail::within::range_in_circle(r, c);
+ }
+};
+
+template <typename Polygon, typename Circle, typename Strategy>
+struct within<polygon_tag, nsphere_tag, Polygon, Circle, Strategy>
+{
+ static inline bool apply(Polygon const& poly, Circle const& c, Strategy const&)
+ {
+ return detail::within::polygon_in_circle(poly, c);
+ }
+};
+
+template <typename M, typename C, typename Strategy>
+struct within<multi_polygon_tag, nsphere_tag, M, C, Strategy>
+{
+ static inline bool apply(M const& m, C const& c)
+ {
+ return detail::within::multi_polygon_in_circle(m, c, Strategy const&);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_ALGORITHMS_WITHIN_HPP
diff --git a/src/boost/geometry/extensions/nsphere/core/access.hpp b/src/boost/geometry/extensions/nsphere/core/access.hpp
new file mode 100644
index 0000000..6e82e8a
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/core/access.hpp
@@ -0,0 +1,52 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_ACCESS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_ACCESS_HPP
+
+
+
+#include <boost/geometry/core/access.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Nsphere, typename CoordinateType, std::size_t Dimension>
+struct access<nsphere_tag, Nsphere, CoordinateType, Dimension>
+{
+ static inline CoordinateType get(Nsphere const& nsphere)
+ {
+ return traits::access<Nsphere, Dimension>::get(nsphere);
+ }
+ static inline void set(Nsphere& s, CoordinateType const& value)
+ {
+ traits::access<Nsphere, Dimension>::set(s, value);
+ }
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_ACCESS_HPP
diff --git a/src/boost/geometry/extensions/nsphere/core/geometry_id.hpp b/src/boost/geometry/extensions/nsphere/core/geometry_id.hpp
new file mode 100644
index 0000000..ccf5cf8
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/core/geometry_id.hpp
@@ -0,0 +1,47 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_GEOMETRY_ID_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_GEOMETRY_ID_HPP
+
+
+#include <boost/geometry/core/geometry_id.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <>
+struct geometry_id<nsphere_tag> : boost::mpl::int_<91> {};
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_GEOMETRY_ID_HPP
diff --git a/src/boost/geometry/extensions/nsphere/core/radius.hpp b/src/boost/geometry/extensions/nsphere/core/radius.hpp
new file mode 100644
index 0000000..4670ad2
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/core/radius.hpp
@@ -0,0 +1,160 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_RADIUS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_RADIUS_HPP
+
+
+#include <cstddef>
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+/*!
+ \brief Traits class to get/set radius of a circle/sphere/(ellipse)
+ \details the radius access meta-functions give read/write access to the radius of a circle or a sphere,
+ or to the major/minor axis or an ellipse, or to one of the 3 equatorial radii of an ellipsoid.
+
+ It should be specialized per geometry, in namespace core_dispatch. Those specializations should
+ forward the call via traits to the geometry class, which could be specified by the user.
+
+ There is a corresponding generic radius_get and radius_set function
+ \par Geometries:
+ - n-sphere (circle,sphere)
+ - upcoming ellipse
+ \par Specializations should provide:
+ - inline static T get(G const& geometry)
+ - inline static void set(G& geometry, T const& radius)
+ \ingroup traits
+*/
+template <typename G, typename T, std::size_t D>
+struct radius_access {};
+
+
+/*!
+ \brief Traits class indicating the type (double,float,...) of the radius of a circle or a sphere
+ \par Geometries:
+ - n-sphere (circle,sphere)
+ - upcoming ellipse
+ \par Specializations should provide:
+ - typedef T type (double,float,int,etc)
+ \ingroup traits
+*/
+template <typename G>
+struct radius_type {};
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename G>
+struct radius_type
+{
+ //typedef core_dispatch_specialization_required type;
+};
+
+/*!
+ \brief radius access meta-functions, used by concept n-sphere and upcoming ellipse.
+*/
+template <typename Tag, typename G, typename T, std::size_t D>
+struct radius_access
+{
+ //static inline T get(G const& ) {}
+ //static inline void set(G& g, T const& value) {}
+};
+
+template <typename S>
+struct radius_type<nsphere_tag, S>
+{
+ typedef typename traits::radius_type<S>::type type;
+};
+
+template <typename S, typename T, std::size_t D>
+struct radius_access<nsphere_tag, S, T, D>
+{
+ BOOST_STATIC_ASSERT((D == 0));
+ static inline T get(S const& s)
+ {
+ return traits::radius_access<S, T, D>::get(s);
+ }
+ static inline void set(S& s, T const& radius)
+ {
+ traits::radius_access<S, T, D>::set(s, radius);
+ }
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename G>
+struct radius_type
+{
+ typedef typename boost::remove_const<G>::type rconst;
+ typedef typename core_dispatch::radius_type<typename tag<G>::type, rconst>::type type;
+};
+
+/*!
+ \brief Function to get radius
+ \return radius of a circle / sphere / ellipse
+ \ingroup access
+ \param geometry the geometry to get the radius from
+ \tparam I index, for circle/sphere always zero, for ellipse major/minor axis,
+ for ellipsoid one of the 3 equatorial radii
+*/
+template <std::size_t I, typename G>
+inline typename radius_type<G>::type get_radius(G const& geometry)
+{
+ typedef typename boost::remove_const<G>::type rconst;
+
+ return core_dispatch::radius_access<typename tag<G>::type, rconst,
+ typename radius_type<G>::type, I>::get(geometry);
+}
+
+/*!
+ \brief Function to set the radius of a circle / sphere / (ellipse)
+ \ingroup access
+ \tparam I index, for circle/sphere always zero, for ellipse major/minor axis,
+ for ellipsoid one of the 3 equatorial radii
+ \param geometry the geometry to change
+ \param radius the radius to set
+*/
+template <std::size_t I, typename G>
+inline void set_radius(G& geometry, typename radius_type<G>::type const& radius)
+{
+ typedef typename boost::remove_const<G>::type rconst;
+
+ core_dispatch::radius_access<typename tag<G>::type, G,
+ typename radius_type<G>::type, I>::set(geometry, radius);
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_RADIUS_HPP
diff --git a/src/boost/geometry/extensions/nsphere/core/replace_point_type.hpp b/src/boost/geometry/extensions/nsphere/core/replace_point_type.hpp
new file mode 100644
index 0000000..ecc2a16
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/core/replace_point_type.hpp
@@ -0,0 +1,48 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_REPLACE_POINT_TYPE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_REPLACE_POINT_TYPE_HPP
+
+
+#include <boost/geometry/core/replace_point_type.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+#include <boost/geometry/extensions/nsphere/geometries/nsphere.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<nsphere_tag, Geometry, NewPointType>
+{
+ typedef typename geometry::coordinate_type<Geometry>::type coortype;
+ typedef model::nsphere<NewPointType, coortype> type;
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_REPLACE_POINT_TYPE_HPP
diff --git a/src/boost/geometry/extensions/nsphere/core/tags.hpp b/src/boost/geometry/extensions/nsphere/core/tags.hpp
new file mode 100644
index 0000000..beac11f
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/core/tags.hpp
@@ -0,0 +1,29 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_TAGS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_TAGS_HPP
+
+
+namespace boost { namespace geometry
+{
+
+
+/// Convenience 2D (circle) or 3D (sphere) n-sphere identifying tag
+struct nsphere_tag {};
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_TAGS_HPP
diff --git a/src/boost/geometry/extensions/nsphere/core/topological_dimension.hpp b/src/boost/geometry/extensions/nsphere/core/topological_dimension.hpp
new file mode 100644
index 0000000..f0e7c9c
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/core/topological_dimension.hpp
@@ -0,0 +1,50 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_TOPOLOGICAL_DIMENSION_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_TOPOLOGICAL_DIMENSION_HPP
+
+
+#include <boost/geometry/core/topological_dimension.hpp>
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+
+// nsphere: 2, but there is discussion. Is it CLOSED? Then 2, but
+// then it should be called "disk"...
+template <>
+struct top_dim<nsphere_tag> : boost::mpl::int_<2> {};
+
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_CORE_TOPOLOGICAL_DIMENSION_HPP
diff --git a/src/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp b/src/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp
new file mode 100644
index 0000000..944eb0d
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp
@@ -0,0 +1,42 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP
+
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP
diff --git a/src/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp b/src/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp
new file mode 100644
index 0000000..03decb4
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp
@@ -0,0 +1,122 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_NSPHERE_CONCEPT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_NSPHERE_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/extensions/nsphere/core/radius.hpp>
+
+namespace boost { namespace geometry { namespace concept {
+
+/*!
+ \brief Checks Nsphere concept (const version)
+ \ingroup concepts
+ \details The ConstNsphere concept check the same as the Nsphere concept,
+ but does not check write access.
+*/
+template <typename Geometry>
+class ConstNsphere
+{
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename radius_type<Geometry>::type radius_type;
+
+
+ template <size_t Dimension, size_t DimensionCount>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ typedef typename coordinate_type<Geometry>::type coordinate_type;
+ const Geometry* s = 0;
+ coordinate_type coord(geometry::get<Dimension>(*s));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker<Dimension + 1, DimensionCount>::apply();
+ }
+ };
+
+ template <size_t DimensionCount>
+ struct dimension_checker<DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public :
+
+ BOOST_CONCEPT_USAGE(ConstNsphere)
+ {
+ static const size_t n = dimension<Geometry>::value;
+ dimension_checker<0, n>::apply();
+ dimension_checker<0, n>::apply();
+
+ // Check radius access
+ Geometry const* s = 0;
+ radius_type coord(geometry::get_radius<0>(*s));
+ boost::ignore_unused_variable_warning(coord);
+ }
+};
+
+
+/*!
+ \brief Checks nsphere concept
+ \ingroup concepts
+*/
+template <typename Geometry>
+class Nsphere
+{
+ BOOST_CONCEPT_ASSERT( (concept::ConstNsphere<Geometry>) );
+
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename radius_type<Geometry>::type radius_type;
+
+
+ template <size_t Dimension, size_t DimensionCount>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ Geometry* s;
+ geometry::set<Dimension>(*s, geometry::get<Dimension>(*s));
+ dimension_checker<Dimension + 1, DimensionCount>::apply();
+ }
+ };
+
+ template <size_t DimensionCount>
+ struct dimension_checker<DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public :
+
+ BOOST_CONCEPT_USAGE(Nsphere)
+ {
+ static const size_t n = dimension<Geometry>::type::value;
+ dimension_checker<0, n>::apply();
+ dimension_checker<0, n>::apply();
+
+ // Check radius access
+ Geometry* s = 0;
+ set_radius<0>(*s, get_radius<0>(*s));
+ }
+};
+
+
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_NSPHERE_CONCEPT_HPP
diff --git a/src/boost/geometry/extensions/nsphere/geometries/nsphere.hpp b/src/boost/geometry/extensions/nsphere/geometries/nsphere.hpp
new file mode 100644
index 0000000..a4ea8af
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/geometries/nsphere.hpp
@@ -0,0 +1,144 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_NSPHERE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_NSPHERE_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/assign.hpp>
+#include <boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+
+/*!
+ \brief Class nsphere: defines a circle or a sphere: a point with radius
+ \ingroup Geometry
+ \details The name nsphere is quite funny but the best description of the class. It can be a circle (2D),
+ a sphere (3D), or higher (hypersphere) or lower. According to Wikipedia this name is the most appropriate.
+ It was mentioned on the Boost list.
+ An alternative is the more fancy name "sphercle" but that might be a bit too much an invention.
+ \note Circle is currently used for selections, for example polygon_in_circle. Currently not all
+ algorithms are implemented for n-spheres.
+ \tparam P point type of the center
+ \tparam T number type of the radius
+ */
+template <typename P, typename T>
+class nsphere
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+
+public:
+
+ typedef T radius_type;
+ typedef typename coordinate_type<P>::type coordinate_type;
+
+ nsphere()
+ : m_radius(0)
+ {
+ detail::assign::assign_value(m_center, coordinate_type());
+ }
+
+ nsphere(P const& center, T const& radius)
+ : m_radius(radius)
+ {
+ geometry::convert(center, m_center);
+ }
+
+ inline P const& center() const { return m_center; }
+ inline T const& radius() const { return m_radius; }
+
+ inline void radius(T const& r) { m_radius = r; }
+ inline P& center() { return m_center; }
+
+private:
+
+ P m_center;
+ T m_radius;
+};
+
+
+} // namespace model
+
+// Traits specializations for n-sphere above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename Point, typename RadiusType>
+struct tag<model::nsphere<Point, RadiusType> >
+{
+ typedef nsphere_tag type;
+};
+
+template <typename Point, typename RadiusType>
+struct point_type<model::nsphere<Point, RadiusType> >
+{
+ typedef Point type;
+};
+
+template <typename Point, typename RadiusType>
+struct radius_type<model::nsphere<Point, RadiusType> >
+{
+ typedef RadiusType type;
+};
+
+template <typename Point, typename CoordinateType, std::size_t Dimension>
+struct access<model::nsphere<Point, CoordinateType>, Dimension>
+{
+ typedef model::nsphere<Point, CoordinateType> nsphere_type;
+
+ static inline CoordinateType get(nsphere_type const& s)
+ {
+ return geometry::get<Dimension>(s.center());
+ }
+
+ static inline void set(nsphere_type& s, CoordinateType const& value)
+ {
+ geometry::set<Dimension>(s.center(), value);
+ }
+};
+
+template <typename Point, typename RadiusType>
+struct radius_access<model::nsphere<Point, RadiusType>, RadiusType, 0>
+{
+ typedef model::nsphere<Point, RadiusType> nsphere_type;
+
+ static inline RadiusType get(nsphere_type const& s)
+ {
+ return s.radius();
+ }
+
+ static inline void set(nsphere_type& s, RadiusType const& value)
+ {
+ s.radius(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_NSPHERE_HPP
diff --git a/src/boost/geometry/extensions/nsphere/nsphere.hpp b/src/boost/geometry/extensions/nsphere/nsphere.hpp
new file mode 100644
index 0000000..04d67d2
--- /dev/null
+++ b/src/boost/geometry/extensions/nsphere/nsphere.hpp
@@ -0,0 +1,37 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_HPP
+
+#include <boost/geometry/extensions/nsphere/core/access.hpp>
+#include <boost/geometry/extensions/nsphere/core/geometry_id.hpp>
+#include <boost/geometry/extensions/nsphere/core/radius.hpp>
+#include <boost/geometry/extensions/nsphere/core/replace_point_type.hpp>
+#include <boost/geometry/extensions/nsphere/core/tags.hpp>
+#include <boost/geometry/extensions/nsphere/core/topological_dimension.hpp>
+
+#include <boost/geometry/extensions/nsphere/geometries/concepts/check.hpp>
+#include <boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp>
+
+#include <boost/geometry/extensions/nsphere/geometries/nsphere.hpp>
+
+#include <boost/geometry/extensions/nsphere/algorithms/append.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/area.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/assign.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/clear.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/envelope.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/num_points.hpp>
+#include <boost/geometry/extensions/nsphere/algorithms/within.hpp>
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_HPP
diff --git a/src/boost/geometry/extensions/strategies/buffer.hpp b/src/boost/geometry/extensions/strategies/buffer.hpp
new file mode 100644
index 0000000..96f94c9
--- /dev/null
+++ b/src/boost/geometry/extensions/strategies/buffer.hpp
@@ -0,0 +1,396 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_HPP
+
+
+// Buffer strategies
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+#define BOOST_GEOMETRY_BUFFER_NO_HELPER_POINTS
+
+
+namespace boost { namespace geometry
+{
+
+
+
+
+namespace strategy { namespace buffer
+{
+
+
+
+/*
+
+ A Buffer-join strategy gets 4 input points.
+ On the two consecutive segments s1 and s2 (joining at vertex v):
+
+ The lines from parallel at s1, s2 (at buffer-distance) end/start
+ in two points perpendicular to the segments: p1 and p2.
+ These parallel lines interesct in point ip
+
+ (s2)
+ |
+ |
+ ^
+ |
+ (p2) |(v)
+ * +----<--- (s1)
+
+ x(ip) *(p1)
+
+
+ So, in clockwise order:
+ v : vertex point
+ p1: perpendicular on left side of segment1<1> (perp1)
+ ip: intersection point
+ p2: perpendicular on left side of segment2<0> (perp2)
+*/
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+template
+<
+ typename PointIn, typename Mapper
+>
+struct join_mapper
+{
+ Mapper const& m_mapper;
+ join_mapper(Mapper const& mapper)
+ : m_mapper(mapper)
+ {}
+
+ template <typename Ring>
+ inline void map(PointIn const& ip, PointIn const& vertex,
+ PointIn const& perp1, PointIn const& perp2) const
+ {
+ Ring corner;
+ corner.push_back(vertex);
+ corner.push_back(perp1);
+ corner.push_back(ip);
+ corner.push_back(perp2);
+ corner.push_back(vertex);
+
+ const_cast<Mapper&>(m_mapper).map(corner,
+ "opacity:0.4;fill:rgb(255,0,0);stroke:rgb(0,0,0);stroke-width:1");
+ }
+};
+#endif
+
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+// Forget this, it will go
+template<typename PointIn, typename PointOut, typename Mapper>
+struct join_miter : public join_mapper<PointIn, Mapper>
+{
+ join_miter(Mapper const& mapper) : join_mapper(mapper) {}
+#else
+
+
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+struct join_miter
+{
+
+#endif
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
+ typedef typename coordinate_type<PointIn>::type coordinate_type;
+
+
+ template <typename Ring>
+ inline void apply(PointIn const& ip, PointIn const& vertex,
+ PointIn const& perp1, PointIn const& perp2,
+ coordinate_type const& buffer_distance,
+ Ring& buffered) const
+ {
+ coordinate_type zero = 0;
+ int signum = buffer_distance > zero
+ ? 1
+ : buffer_distance < zero
+ ? -1
+ : 0;
+
+ if (side::apply(perp1, ip, perp2) == signum)
+ {
+
+#ifdef BOOST_GEOMETRY_BUFFER_NO_HELPER_POINTS
+ // Because perp1 crosses perp2 at IP, it is not necessary to
+ // include IP
+ buffered.push_back(ip);
+#else
+ // If it is concave (corner to left), add helperline
+ // The helper-line IS essential for buffering holes. Without,
+ // holes might be generated, while they should NOT be there.
+ // DOES NOT WORK ALWAYS buffered.push_back(ip);
+ // We might consider to make it optional (because more efficient)
+ buffered.push_back(perp1);
+ buffered.push_back(perp2);
+#endif
+ }
+ else
+ {
+ PointIn p = ip;
+
+ // Normalize it and give it X*dist.
+ coordinate_type dx = get<0>(ip) - get<0>(vertex);
+ coordinate_type dy = get<1>(ip) - get<1>(vertex);
+
+ coordinate_type length = sqrt(dx * dx + dy * dy);
+
+ // TODO: make max-mitre-limit flexible
+ coordinate_type ten = 10.0;
+ coordinate_type zero_seven = 0.7;
+
+ coordinate_type max = ten * geometry::math::abs(buffer_distance);
+
+ if (length > max)
+ {
+
+ coordinate_type prop = zero_seven * buffer_distance;
+ prop /= length;
+ set<0>(p, get<0>(vertex) + dx * prop);
+ set<1>(p, get<1>(vertex) + dy * prop);
+
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER
+ std::cout << length << std::endl;
+#endif
+ }
+
+ buffered.push_back(p);
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ map<Ring>(ip, vertex, perp1, perp2);
+#endif
+ }
+
+
+ }
+};
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+// Forget this, it will go
+template<typename PointIn, typename PointOut, typename Mapper>
+struct join_bevel : public join_mapper<PointIn, Mapper>
+{
+ join_bevel(Mapper const& mapper) : join_mapper(mapper) {}
+#else
+
+
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+struct join_bevel
+{
+#endif
+
+
+ typedef typename coordinate_type<PointIn>::type coordinate_type;
+
+ template <typename Ring>
+ inline void apply(PointIn const& ip, PointIn const& vertex,
+ PointIn const& perp1, PointIn const& perp2,
+ coordinate_type const& buffer_distance,
+ Ring& buffered) const
+ {
+ buffered.push_back(perp1);
+ buffered.push_back(perp2);
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ map<Ring>(ip, vertex, perp1, perp2);
+#endif
+ }
+};
+
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+// Forget this, it will go
+template<typename PointIn, typename PointOut, typename Mapper>
+struct join_round : public join_mapper<PointIn, Mapper>
+{
+ join_round(Mapper const& mapper, int max_level = 4)
+ : join_mapper(mapper)
+ , m_max_level(max_level)
+ {}
+#else
+
+
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+struct join_round
+{
+ inline join_round(int max_level = 4)
+ : m_max_level(max_level)
+ {}
+#endif
+
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
+ typedef typename coordinate_type<PointOut>::type coordinate_type;
+ int m_max_level;
+
+
+ template <typename Ring>
+ inline void mid_points(PointIn const& vertex,
+ PointIn const& p1, PointIn const& p2,
+ coordinate_type const& buffer_distance,
+ Ring& buffered,
+ int level = 1) const
+ {
+ // Generate 'vectors'
+ coordinate_type vp1_x = get<0>(p1) - get<0>(vertex);
+ coordinate_type vp1_y = get<1>(p1) - get<1>(vertex);
+
+ coordinate_type vp2_x = (get<0>(p2) - get<0>(vertex));
+ coordinate_type vp2_y = (get<1>(p2) - get<1>(vertex));
+
+ // Average them to generate vector in between
+ coordinate_type two = 2;
+ coordinate_type v_x = (vp1_x + vp2_x) / two;
+ coordinate_type v_y = (vp1_y + vp2_y) / two;
+
+ coordinate_type length2 = sqrt(v_x * v_x + v_y * v_y);
+
+ coordinate_type prop = buffer_distance / length2;
+
+ PointIn mid_point;
+ set<0>(mid_point, get<0>(vertex) + v_x * prop);
+ set<1>(mid_point, get<1>(vertex) + v_y * prop);
+
+ if (level < m_max_level)
+ {
+ mid_points(vertex, p1, mid_point, buffer_distance, buffered, level + 1);
+ }
+ buffered.push_back(mid_point);
+ if (level < m_max_level)
+ {
+ mid_points(vertex, mid_point, p2, buffer_distance, buffered, level + 1);
+ }
+
+ }
+
+
+ template <typename Ring>
+ inline void apply(PointIn const& ip, PointIn const& vertex,
+ PointIn const& perp1, PointIn const& perp2,
+ coordinate_type const& buffer_distance,
+ Ring& buffered) const
+ {
+ coordinate_type zero = 0;
+ int signum = buffer_distance > zero
+ ? 1
+ : buffer_distance < zero
+ ? -1
+ : 0;
+
+ if (side::apply(perp1, ip, perp2) == signum)
+ {
+#ifdef BOOST_GEOMETRY_BUFFER_NO_HELPER_POINTS
+ buffered.push_back(ip);
+#else
+ // If it is concave (corner to left), add helperline
+ buffered.push_back(perp1);
+ buffered.push_back(perp2);
+#endif
+ }
+ else
+ {
+ // Generate 'vectors'
+ coordinate_type vix = (get<0>(ip) - get<0>(vertex));
+ coordinate_type viy = (get<1>(ip) - get<1>(vertex));
+
+ coordinate_type length_i = sqrt(vix * vix + viy * viy);
+
+
+ coordinate_type const bd = geometry::math::abs(buffer_distance);
+ coordinate_type prop = bd / length_i;
+
+ PointIn bp;
+ set<0>(bp, get<0>(vertex) + vix * prop);
+ set<1>(bp, get<1>(vertex) + viy * prop);
+
+ if (m_max_level <= 1)
+ {
+ buffered.push_back(perp1);
+ if (m_max_level == 1)
+ {
+ buffered.push_back(bp);
+ }
+ buffered.push_back(perp2);
+ }
+ else
+ {
+ buffered.push_back(perp1);
+ mid_points(vertex, perp1, bp, bd, buffered);
+ mid_points(vertex, bp, perp2, bd, buffered);
+ buffered.push_back(perp2);
+ }
+
+#ifdef BOOST_GEOMETRY_DEBUG_WITH_MAPPER
+ map<Ring>(bp, vertex, perp1, perp2);
+#endif
+ }
+ }
+};
+
+
+
+template
+<
+ typename CoordinateType
+>
+class distance_assymetric
+{
+public :
+ distance_assymetric(CoordinateType const& left,
+ CoordinateType const& right)
+ : m_left(left)
+ , m_right(right)
+ {}
+
+ template <typename Point>
+ inline CoordinateType apply(Point const& , Point const& ,
+ buffer_side_selector side) const
+ {
+ return side == buffer_side_left ? m_left : m_right;
+ }
+
+private :
+ CoordinateType m_left;
+ CoordinateType m_right;
+};
+
+
+}} // namespace strategy::buffer
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_HPP
diff --git a/src/boost/geometry/extensions/strategies/buffer_join_round.hpp b/src/boost/geometry/extensions/strategies/buffer_join_round.hpp
new file mode 100644
index 0000000..5e4549c
--- /dev/null
+++ b/src/boost/geometry/extensions/strategies/buffer_join_round.hpp
@@ -0,0 +1,176 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_ROUND_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_ROUND_HPP
+
+
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/arithmetic/dot_product.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+#define BOOST_GEOMETRY_BUFFER_NO_HELPER_POINTS
+
+
+namespace boost { namespace geometry
+{
+
+
+
+
+namespace strategy { namespace buffer
+{
+
+
+
+
+template<typename PointOut>
+struct join_round2
+{
+ typedef PointOut vector_type;
+
+ template <typename Vector, typename Point1, typename Point2>
+ static inline Vector create_vector(Point1 const& p1, Point2 const& p2)
+ {
+ Vector v;
+ geometry::convert(p1, v);
+ subtract_point(v, p2);
+ return v;
+ }
+
+ inline join_round2(int max_level = 4)
+ : m_max_level(max_level)
+ {}
+
+ typedef typename coordinate_type<PointOut>::type coordinate_type;
+ int m_max_level;
+
+
+ template <typename OutputIterator, typename Point, typename PointP, typename Point1, typename Point2>
+ inline void mid_points(Point const& vertex, PointP const& perpendicular,
+ Point1 const& p1, Point2 const& p2,
+ coordinate_type const& buffer_distance,
+ coordinate_type const& max_distance,
+ OutputIterator out,
+ int level = 1) const
+ {
+ // Generate 'vectors'
+ coordinate_type vp1_x = get<0>(p1) - get<0>(vertex);
+ coordinate_type vp1_y = get<1>(p1) - get<1>(vertex);
+
+ coordinate_type vp2_x = (get<0>(p2) - get<0>(vertex));
+ coordinate_type vp2_y = (get<1>(p2) - get<1>(vertex));
+
+ // Average them to generate vector in between
+ coordinate_type two = 2;
+ coordinate_type v_x = (vp1_x + vp2_x) / two;
+ coordinate_type v_y = (vp1_y + vp2_y) / two;
+
+ coordinate_type between_length = sqrt(v_x * v_x + v_y * v_y);
+
+ coordinate_type const positive_buffer_distance = geometry::math::abs(buffer_distance);
+ coordinate_type prop = positive_buffer_distance / between_length;
+
+ PointOut mid_point;
+ set<0>(mid_point, get<0>(vertex) + v_x * prop);
+ set<1>(mid_point, get<1>(vertex) + v_y * prop);
+
+ if (buffer_distance > max_distance)
+ {
+ // Calculate point projected on original perpendicular segment,
+ // using vector maths
+ vector_type v = create_vector<vector_type>(perpendicular, vertex);
+ vector_type w = create_vector<vector_type>(mid_point, vertex);
+
+ coordinate_type c1 = dot_product(w, v);
+ if (c1 > 0)
+ {
+ coordinate_type c2 = dot_product(v, v);
+ if (c2 > c1)
+ {
+ coordinate_type b = c1 / c2;
+
+ PointOut projected_point;
+
+ multiply_value(v, b);
+ geometry::convert(vertex, projected_point);
+ add_point(projected_point, v);
+
+ coordinate_type projected_distance = geometry::distance(projected_point, mid_point);
+
+ if (projected_distance > max_distance)
+ {
+ // Do not generate from here on.
+ return;
+ }
+ }
+ }
+ }
+
+ if (level < m_max_level)
+ {
+ mid_points(vertex, perpendicular, p1, mid_point, positive_buffer_distance, max_distance, out, level + 1);
+ }
+ *out++ = mid_point;
+ if (level < m_max_level)
+ {
+ mid_points(vertex, perpendicular, mid_point, p2, positive_buffer_distance, max_distance, out, level + 1);
+ }
+ }
+
+
+ template <typename OutputIterator, typename Point, typename Point2>
+ inline OutputIterator apply(Point const& vertex,
+ Point2 const& perpendicular,
+ Point2 const& p1, Point2 const& p2,
+ coordinate_type const& buffer_distance,
+ coordinate_type const& max_distance,
+ OutputIterator out) const
+ {
+ mid_points(vertex, perpendicular, p1, p2, buffer_distance, max_distance, out);
+ return out;
+ }
+};
+
+
+template<typename PointOut>
+struct join_none
+{
+ template <typename OutputIterator, typename Point, typename Point2,
+ typename DistanceType>
+ inline OutputIterator apply(Point const& ,
+ Point2 const& ,
+ Point2 const& , Point2 const& ,
+ DistanceType const& ,
+ DistanceType const& ,
+ OutputIterator out) const
+ {
+ return out;
+ }
+};
+
+
+}} // namespace strategy::buffer
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_ROUND_HPP
diff --git a/src/boost/geometry/extensions/strategies/buffer_side.hpp b/src/boost/geometry/extensions/strategies/buffer_side.hpp
new file mode 100644
index 0000000..33e658d
--- /dev/null
+++ b/src/boost/geometry/extensions/strategies/buffer_side.hpp
@@ -0,0 +1,31 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_SIDE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_SIDE_HPP
+
+
+
+namespace boost { namespace geometry
+{
+
+
+// TODO: consider if this enum can be placed in another headerfile
+// or probably there will be more enum's or constants for the buffer
+enum buffer_side_selector { buffer_side_left, buffer_side_right };
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_SIDE_HPP
diff --git a/src/boost/geometry/extensions/strategies/parse.hpp b/src/boost/geometry/extensions/strategies/parse.hpp
new file mode 100644
index 0000000..de0cdc2
--- /dev/null
+++ b/src/boost/geometry/extensions/strategies/parse.hpp
@@ -0,0 +1,41 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_EXTENSIONS_PARSE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_EXTENSIONS_PARSE_HPP
+
+#include <boost/geometry/strategies/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+/*!
+ \brief Tagraits class binding a parsing strategy to a coordinate system
+ \ingroup parse
+ \tparam Tag tag of coordinate system of point-type
+ \tparam CoordinateSystem coordinate system
+*/
+template <typename Tag, typename CoordinateSystem>
+struct strategy_parse
+{
+ typedef strategy::not_implemented type;
+};
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_EXTENSIONS_PARSE_HPP
diff --git a/src/boost/geometry/extensions/util/get_cs_as_radian.hpp b/src/boost/geometry/extensions/util/get_cs_as_radian.hpp
new file mode 100644
index 0000000..03a20e5
--- /dev/null
+++ b/src/boost/geometry/extensions/util/get_cs_as_radian.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_UTIL_GET_CS_AS_RADIAN_HPP
+#define BOOST_GEOMETRY_UTIL_GET_CS_AS_RADIAN_HPP
+
+// obsolete? It is not used anymore (get_as_radian is usually OK)
+
+#include <boost/geometry/core/cs.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+ /*!
+ \brief Small meta-function defining the specified coordinate system,
+ but then in radian units
+ */
+ template <typename CoordinateSystem>
+ struct get_cs_as_radian {};
+
+ template <typename Units>
+ struct get_cs_as_radian<cs::geographic<Units> >
+ {
+ typedef cs::geographic<radian> type;
+ };
+
+ template <typename Units>
+ struct get_cs_as_radian<cs::spherical<Units> >
+ {
+ typedef cs::spherical<radian> type;
+ };
+
+} // namespace detail
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_GET_CS_AS_RADIAN_HPP
diff --git a/src/boost/geometry/extensions/util/replace_point_type.hpp b/src/boost/geometry/extensions/util/replace_point_type.hpp
new file mode 100644
index 0000000..f1300f2
--- /dev/null
+++ b/src/boost/geometry/extensions/util/replace_point_type.hpp
@@ -0,0 +1,98 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_UTIL_REPLACE_POINT_TYPE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_UTIL_REPLACE_POINT_TYPE_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+// For now: use ggl-provided geometries
+// TODO: figure out how to get the class and replace the type
+// TODO: take "const" into account
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/linestring.hpp>
+#include <boost/geometry/geometries/ring.hpp>
+#include <boost/geometry/geometries/polygon.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/geometries/box.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+template <typename GeometryTag, typename Geometry, typename NewPointType>
+struct replace_point_type {};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<point_tag, Geometry, NewPointType>
+{
+ typedef NewPointType type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<linestring_tag, Geometry, NewPointType>
+{
+ typedef model::linestring<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<segment_tag, Geometry, NewPointType>
+{
+ typedef model::segment<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<ring_tag, Geometry, NewPointType>
+{
+ typedef model::ring<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<box_tag, Geometry, NewPointType>
+{
+ typedef model::box<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<polygon_tag, Geometry, NewPointType>
+{
+ typedef model::polygon<NewPointType> type;
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type : core_dispatch::replace_point_type
+ <
+ typename tag<Geometry>::type,
+ typename boost::remove_const<Geometry>::type,
+ NewPointType
+ >
+{};
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_UTIL_REPLACE_POINT_TYPE_HPP
diff --git a/src/boost/geometry/extensions/views/enveloped_view.hpp b/src/boost/geometry/extensions/views/enveloped_view.hpp
new file mode 100644
index 0000000..0e654cd
--- /dev/null
+++ b/src/boost/geometry/extensions/views/enveloped_view.hpp
@@ -0,0 +1,126 @@
+// Boost.Range (aka GGL, Generic Range Library)
+//
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_ENVELOPED_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_ENVELOPED_VIEW_HPP
+
+
+// Note the addition of this whole file was committed to SVN by accident,
+// probably obsolete
+
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+
+template <typename Range, typename Box, std::size_t Dimension>
+class enveloped_view
+{
+public :
+ typedef typename boost::range_iterator<Range const>::type const_iterator;
+ typedef typename boost::range_iterator<Range>::type iterator;
+
+ explicit enveloped_view(Range& range, Box const& box, int dir)
+ : m_begin(boost::begin(range))
+ , m_end(boost::end(range))
+ {
+ find_first(dir, m_begin, m_end, box);
+ find_last(dir, m_begin, m_end, box);
+
+ // Assignment of const iterator to iterator seems no problem,
+ // at least not for MSVC and GCC
+ m_const_begin = m_begin;
+ m_const_end = m_end;
+ // Otherwise: repeat
+ //find_first(dir, m_const_begin, m_const_end);
+ //find_last(dir, m_const_begin, m_const_end);
+ }
+
+ const_iterator begin() const { return m_const_begin; }
+ const_iterator end() const { return m_const_end; }
+
+ iterator begin() { return m_begin; }
+ iterator end() { return m_end; }
+
+private :
+ const_iterator m_const_begin, m_const_end;
+ iterator m_begin, m_end;
+
+ template <typename Point>
+ inline bool preceding(short int dir, Point const& point, Box const& box)
+ {
+ return (dir == 1 && get<Dimension>(point) < get<0, Dimension>(box))
+ || (dir == -1 && get<Dimension>(point) > get<1, Dimension>(box));
+ }
+
+ template <typename Point>
+ inline bool exceeding(short int dir, Point const& point, Box const& box)
+ {
+ return (dir == 1 && get<Dimension>(point) > get<1, Dimension>(box))
+ || (dir == -1 && get<Dimension>(point) < get<0, Dimension>(box));
+ }
+
+ template <typename Iterator>
+ void find_first(int dir, Iterator& begin, Iterator const end, Box const& box)
+ {
+ if (begin != end)
+ {
+ if (exceeding(dir, *begin, box))
+ {
+ // First obvious check
+ begin = end;
+ return;
+ }
+
+ iterator it = begin;
+ iterator prev = it++;
+ for(; it != end && preceding(dir, *it, box); ++it, ++prev) {}
+ begin = prev;
+ }
+ }
+
+ template <typename Iterator>
+ void find_last(int dir, Iterator& begin, Iterator& end, Box const& box)
+ {
+ if (begin != end)
+ {
+ iterator it = begin;
+ iterator prev = it++;
+ for(; it != end && ! exceeding(dir, *prev, box); ++it, ++prev) {}
+ if (it == end && prev != end && preceding(dir, *prev, box))
+ {
+ // Last obvious check (not done before to not refer to *(end-1))
+ begin = end;
+ }
+ else
+ {
+ end = it;
+ }
+ }
+ }
+
+};
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_ENVELOPED_VIEW_HPP
diff --git a/src/boost/geometry/extensions/views/section_view.hpp b/src/boost/geometry/extensions/views/section_view.hpp
new file mode 100644
index 0000000..8e0dcce
--- /dev/null
+++ b/src/boost/geometry/extensions/views/section_view.hpp
@@ -0,0 +1,73 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_SECTION_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_SECTION_VIEW_HPP
+
+// Note the addition of this whole file was committed to SVN by accident,
+// probably obsolete
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/util/add_const_if_c.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+template <typename Geometry, typename Section>
+class section_view
+{
+ typedef typename detail::range_type<Geometry>::type range_type;
+public :
+ typedef typename boost::range_iterator
+ <
+ range_type
+ >::type iterator;
+ typedef typename boost::range_iterator
+ <
+ range_type const
+ >::type const_iterator;
+
+ explicit section_view(Geometry& geometry, Section const& section)
+ {
+ get_section(geometry, section, m_begin, m_end);
+ }
+
+ const_iterator begin() const { return m_begin; }
+ const_iterator end() const { return m_end; }
+ iterator begin() { return m_begin; }
+ iterator end() { return m_end; }
+
+private :
+ // Might be replaced declaring as BOOST_AUTO
+ typedef typename boost::range_iterator
+ <
+ typename add_const_if_c
+ <
+ boost::is_const<Geometry>::value,
+ range_type
+ >::type
+ >::type iterator_type;
+
+ iterator_type m_begin, m_end;
+};
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_SECTION_VIEW_HPP
diff --git a/src/boost/geometry/geometries/adapted/boost_array.hpp b/src/boost/geometry/geometries/adapted/boost_array.hpp
new file mode 100644
index 0000000..275ccb5
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_array.hpp
@@ -0,0 +1,120 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010 Alfredo Correa
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_ARRAY_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_ARRAY_HPP
+
+
+#ifdef BOOST_GEOMETRY_ADAPTED_BOOST_ARRAY_TAG_DEFINED
+#error Include either "boost_array_as_point" or \
+ "boost_array_as_linestring" or "boost_array_as_ring" \
+ or "boost_array_as_multi_point" to adapt a boost_array
+#endif
+
+#define BOOST_GEOMETRY_ADAPTED_BOOST_ARRAY_TAG_DEFINED
+
+
+#include <cstddef>
+
+#include <boost/type_traits/is_arithmetic.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/array.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+// Create class and specialization to indicate the tag
+// for normal cases and the case that the type of the c-array is arithmetic
+template <bool>
+struct boost_array_tag
+{
+ typedef geometry_not_recognized_tag type;
+};
+
+
+template <>
+struct boost_array_tag<true>
+{
+ typedef point_tag type;
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+// Assign the point-tag, preventing arrays of points getting a point-tag
+template <typename CoordinateType, std::size_t DimensionCount>
+struct tag<boost::array<CoordinateType, DimensionCount> >
+ : detail::boost_array_tag<boost::is_arithmetic<CoordinateType>::value> {};
+
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct coordinate_type<boost::array<CoordinateType, DimensionCount> >
+{
+ typedef CoordinateType type;
+};
+
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct dimension<boost::array<CoordinateType, DimensionCount> >: boost::mpl::int_<DimensionCount> {};
+
+
+template <typename CoordinateType, std::size_t DimensionCount, std::size_t Dimension>
+struct access<boost::array<CoordinateType, DimensionCount>, Dimension>
+{
+ static inline CoordinateType get(boost::array<CoordinateType, DimensionCount> const& a)
+ {
+ return a[Dimension];
+ }
+
+ static inline void set(boost::array<CoordinateType, DimensionCount>& a,
+ CoordinateType const& value)
+ {
+ a[Dimension] = value;
+ }
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#define BOOST_GEOMETRY_REGISTER_BOOST_ARRAY_CS(CoordinateSystem) \
+ namespace boost { namespace geometry { namespace traits { \
+ template <class T, std::size_t N> \
+ struct coordinate_system<boost::array<T, N> > \
+ { \
+ typedef CoordinateSystem type; \
+ }; \
+ }}}
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_ARRAY_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_fusion.hpp b/src/boost/geometry/geometries/adapted/boost_fusion.hpp
new file mode 100644
index 0000000..a9aba91
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_fusion.hpp
@@ -0,0 +1,172 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2011-2012 Akira Takahashi
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_FUSION_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_FUSION_HPP
+
+
+#include <cstddef>
+
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/fusion/include/tag_of.hpp>
+#include <boost/fusion/include/front.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/fusion/mpl.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/count_if.hpp>
+#include <boost/mpl/pop_front.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/front.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace fusion_adapt_detail
+{
+
+template <class Sequence>
+struct all_same :
+ boost::mpl::bool_<
+ boost::mpl::count_if<
+ Sequence,
+ boost::is_same<
+ typename boost::mpl::front<Sequence>::type,
+ boost::mpl::_
+ >
+ >::value == boost::mpl::size<Sequence>::value
+ >
+{};
+
+template <class Sequence>
+struct is_coordinate_size : boost::mpl::bool_<
+ boost::fusion::result_of::size<Sequence>::value == 2 ||
+ boost::fusion::result_of::size<Sequence>::value == 3> {};
+
+template<typename Sequence>
+struct is_fusion_sequence
+ : mpl::and_<boost::fusion::traits::is_sequence<Sequence>,
+ fusion_adapt_detail::is_coordinate_size<Sequence>,
+ fusion_adapt_detail::all_same<Sequence> >
+{};
+
+
+} // namespace fusion_adapt_detail
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+// Boost Fusion Sequence, 2D or 3D
+template <typename Sequence>
+struct coordinate_type
+ <
+ Sequence,
+ typename boost::enable_if
+ <
+ fusion_adapt_detail::is_fusion_sequence<Sequence>
+ >::type
+ >
+{
+ typedef typename boost::mpl::front<Sequence>::type type;
+};
+
+
+template <typename Sequence>
+struct dimension
+ <
+ Sequence,
+ typename boost::enable_if
+ <
+ fusion_adapt_detail::is_fusion_sequence<Sequence>
+ >::type
+ > : boost::mpl::size<Sequence>
+{};
+
+
+template <typename Sequence, std::size_t Dimension>
+struct access
+ <
+ Sequence,
+ Dimension,
+ typename boost::enable_if
+ <
+ fusion_adapt_detail::is_fusion_sequence<Sequence>
+ >::type
+ >
+{
+ typedef typename coordinate_type<Sequence>::type ctype;
+
+ static inline ctype get(Sequence const& point)
+ {
+ return boost::fusion::at_c<Dimension>(point);
+ }
+
+ template <class CoordinateType>
+ static inline void set(Sequence& point, CoordinateType const& value)
+ {
+ boost::fusion::at_c<Dimension>(point) = value;
+ }
+};
+
+
+template <typename Sequence>
+struct tag
+ <
+ Sequence,
+ typename boost::enable_if
+ <
+ fusion_adapt_detail::is_fusion_sequence<Sequence>
+ >::type
+ >
+{
+ typedef point_tag type;
+};
+
+
+} // namespace traits
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+// Convenience registration macro to bind a Fusion sequence to a CS
+#define BOOST_GEOMETRY_REGISTER_BOOST_FUSION_CS(CoordinateSystem) \
+ namespace boost { namespace geometry { namespace traits { \
+ template <typename Sequence> \
+ struct coordinate_system \
+ < \
+ Sequence, \
+ typename boost::enable_if \
+ < \
+ fusion_adapt_detail::is_fusion_sequence<Sequence> \
+ >::type \
+ > \
+ { typedef CoordinateSystem type; }; \
+ }}}
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_FUSION_HPP
diff --git a/src/boost/geometry/geometries/adapted/boost_polygon.hpp b/src/boost/geometry/geometries/adapted/boost_polygon.hpp
new file mode 100644
index 0000000..fed2362
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_polygon.hpp
@@ -0,0 +1,18 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HPP
+
+#include <boost/geometry/geometries/adapted/boost_polygon/point.hpp>
+#include <boost/geometry/geometries/adapted/boost_polygon/box.hpp>
+#include <boost/geometry/geometries/adapted/boost_polygon/ring.hpp>
+#include <boost/geometry/geometries/adapted/boost_polygon/polygon.hpp>
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_polygon/box.hpp b/src/boost/geometry/geometries/adapted/boost_polygon/box.hpp
new file mode 100644
index 0000000..87c3b60
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_polygon/box.hpp
@@ -0,0 +1,141 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_BOX_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_BOX_HPP
+
+// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
+// boost::polygon::rectangle_data -> boost::geometry::box
+
+
+#include <boost/polygon/polygon.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+
+template <typename CoordinateType>
+struct tag<boost::polygon::rectangle_data<CoordinateType> >
+{
+ typedef box_tag type;
+};
+
+
+template <typename CoordinateType>
+struct point_type<boost::polygon::rectangle_data<CoordinateType> >
+{
+ // Not sure what to do here. Boost.Polygon's rectangle does NOT define its
+ // point_type (but uses it...)
+ typedef boost::polygon::point_data<CoordinateType> type;
+};
+
+
+template <typename CoordinateType>
+struct indexed_access
+<
+ boost::polygon::rectangle_data<CoordinateType>,
+ min_corner, 0
+>
+{
+ typedef boost::polygon::rectangle_data<CoordinateType> box_type;
+
+ static inline CoordinateType get(box_type const& b)
+ {
+ return boost::polygon::xl(b);
+ }
+
+ static inline void set(box_type& b, CoordinateType const& value)
+ {
+ boost::polygon::xl(b, value);
+ }
+};
+
+
+template <typename CoordinateType>
+struct indexed_access
+<
+ boost::polygon::rectangle_data<CoordinateType>,
+ min_corner, 1
+>
+{
+ typedef boost::polygon::rectangle_data<CoordinateType> box_type;
+
+ static inline CoordinateType get(box_type const& b)
+ {
+ return boost::polygon::yl(b);
+ }
+
+ static inline void set(box_type& b, CoordinateType const& value)
+ {
+ boost::polygon::yl(b, value);
+ }
+};
+
+
+template <typename CoordinateType>
+struct indexed_access
+<
+ boost::polygon::rectangle_data<CoordinateType>,
+ max_corner, 0
+>
+{
+ typedef boost::polygon::rectangle_data<CoordinateType> box_type;
+
+ static inline CoordinateType get(box_type const& b)
+ {
+ return boost::polygon::xh(b);
+ }
+
+ static inline void set(box_type& b, CoordinateType const& value)
+ {
+ boost::polygon::xh(b, value);
+ }
+};
+
+
+template <typename CoordinateType>
+struct indexed_access
+<
+ boost::polygon::rectangle_data<CoordinateType>,
+ max_corner, 1
+>
+{
+ typedef boost::polygon::rectangle_data<CoordinateType> box_type;
+
+ static inline CoordinateType get(box_type const& b)
+ {
+ return boost::polygon::yh(b);
+ }
+
+ static inline void set(box_type& b, CoordinateType const& value)
+ {
+ boost::polygon::yh(b, value);
+ }
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_BOX_HPP
diff --git a/src/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp b/src/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp
new file mode 100644
index 0000000..c9c1bc7
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp
@@ -0,0 +1,84 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLE_ITERATOR_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLE_ITERATOR_HPP
+
+// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
+// boost::polygon::polygon_with_holes_data -> boost::geometry::polygon
+// hole_iterator -> returning ring_proxy's instead of normal polygon_data
+
+#include <boost/polygon/polygon.hpp>
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace adapt { namespace bp
+{
+
+
+template <typename Polygon, typename RingProxy>
+class hole_iterator
+ : public ::boost::iterator_facade
+ <
+ hole_iterator<Polygon, RingProxy>,
+ RingProxy, // value type
+ boost::forward_traversal_tag,
+ RingProxy // reference type
+ >
+{
+public :
+ typedef typename boost::polygon::polygon_with_holes_traits
+ <
+ Polygon
+ >::iterator_holes_type ith_type;
+
+ explicit inline hole_iterator(Polygon& polygon, ith_type const it)
+ : m_polygon(polygon)
+ , m_base(it)
+ {
+ }
+
+ typedef std::ptrdiff_t difference_type;
+
+private:
+ friend class boost::iterator_core_access;
+
+ inline RingProxy dereference() const
+ {
+ return RingProxy(m_polygon, this->m_base);
+ }
+
+ inline void increment() { ++m_base; }
+ inline void decrement() { --m_base; }
+ inline void advance(difference_type n)
+ {
+ for (int i = 0; i < n; i++)
+ {
+ ++m_base;
+ }
+ }
+
+ inline bool equal(hole_iterator<Polygon, RingProxy> const& other) const
+ {
+ return this->m_base == other.m_base;
+ }
+
+ Polygon& m_polygon;
+ ith_type m_base;
+};
+
+
+}}}}
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLE_ITERATOR_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp b/src/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp
new file mode 100644
index 0000000..c2a6a44
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp
@@ -0,0 +1,204 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP
+
+// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
+// boost::polygon::polygon_with_holes_data -> boost::geometry::polygon
+// pair{begin_holes, begin_holes} -> interior_proxy
+
+#include <boost/polygon/polygon.hpp>
+
+#include <boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp>
+#include <boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace adapt { namespace bp
+{
+
+
+// Polygon should implement the boost::polygon::polygon_with_holes_concept
+// Specify constness in the template parameter if necessary
+template<typename Polygon>
+struct holes_proxy
+{
+ typedef ring_proxy
+ <
+ typename boost::mpl::if_
+ <
+ typename boost::is_const<Polygon>,
+ Polygon const,
+ Polygon
+ >::type
+ > proxy_type;
+ typedef hole_iterator<Polygon, proxy_type> iterator_type;
+
+ // The next line does not work probably because coordinate_type is part of the
+ // polygon_traits, but not of the polygon_with_holes_traits
+ // typedef typename boost::polygon::polygon_traits<Polygon>::coordinate_type coordinate_type;
+
+ // So we use:
+ typedef typename Polygon::coordinate_type coordinate_type;
+
+ inline holes_proxy(Polygon& p)
+ : polygon(p)
+ {}
+
+ inline void clear()
+ {
+ Polygon empty;
+ // Clear the holes
+ polygon.set_holes
+ (
+ boost::polygon::begin_holes(empty),
+ boost::polygon::end_holes(empty)
+ );
+ }
+
+ inline void resize(std::size_t new_size)
+ {
+ std::vector<boost::polygon::polygon_data<coordinate_type> > temporary_copy
+ (
+ boost::polygon::begin_holes(polygon),
+ boost::polygon::end_holes(polygon)
+ );
+ temporary_copy.resize(new_size);
+ polygon.set_holes(temporary_copy.begin(), temporary_copy.end());
+ }
+
+ template <typename Ring>
+ inline void push_back(Ring const& ring)
+ {
+ std::vector<boost::polygon::polygon_data<coordinate_type> > temporary_copy
+ (
+ boost::polygon::begin_holes(polygon),
+ boost::polygon::end_holes(polygon)
+ );
+ boost::polygon::polygon_data<coordinate_type> added;
+ boost::polygon::set_points(added, ring.begin(), ring.end());
+ temporary_copy.push_back(added);
+ polygon.set_holes(temporary_copy.begin(), temporary_copy.end());
+ }
+
+
+ Polygon& polygon;
+};
+
+
+// Support holes_proxy for Boost.Range ADP
+
+// Const versions
+template<typename Polygon>
+inline typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type
+ range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon const> const& proxy)
+{
+ typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type
+ begin(proxy.polygon, boost::polygon::begin_holes(proxy.polygon));
+ return begin;
+}
+
+template<typename Polygon>
+inline typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type
+ range_end(boost::geometry::adapt::bp::holes_proxy<Polygon const> const& proxy)
+{
+ typename boost::geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type
+ end(proxy.polygon, boost::polygon::end_holes(proxy.polygon));
+ return end;
+}
+
+// Mutable versions
+template<typename Polygon>
+inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type
+ range_begin(boost::geometry::adapt::bp::holes_proxy<Polygon>& proxy)
+{
+ typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type
+ begin(proxy.polygon, boost::polygon::begin_holes(proxy.polygon));
+ return begin;
+}
+
+template<typename Polygon>
+inline typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type
+ range_end(boost::geometry::adapt::bp::holes_proxy<Polygon>& proxy)
+{
+ typename boost::geometry::adapt::bp::holes_proxy<Polygon>::iterator_type
+ end(proxy.polygon, boost::polygon::end_holes(proxy.polygon));
+ return end;
+}
+
+
+}}
+
+namespace traits
+{
+
+template <typename Polygon>
+struct rvalue_type<adapt::bp::holes_proxy<Polygon> >
+{
+ typedef adapt::bp::holes_proxy<Polygon> type;
+};
+
+
+template <typename Polygon>
+struct clear<adapt::bp::holes_proxy<Polygon> >
+{
+ static inline void apply(adapt::bp::holes_proxy<Polygon> proxy)
+ {
+ proxy.clear();
+ }
+};
+
+template <typename Polygon>
+struct resize<adapt::bp::holes_proxy<Polygon> >
+{
+ static inline void apply(adapt::bp::holes_proxy<Polygon> proxy, std::size_t new_size)
+ {
+ proxy.resize(new_size);
+ }
+};
+
+template <typename Polygon>
+struct push_back<adapt::bp::holes_proxy<Polygon> >
+{
+ template <typename Ring>
+ static inline void apply(adapt::bp::holes_proxy<Polygon> proxy, Ring const& ring)
+ {
+ proxy.push_back(ring);
+ }
+};
+
+
+
+} // namespace traits
+
+
+}}
+
+
+// Specialize holes_proxy for Boost.Range
+namespace boost
+{
+ template<typename Polygon>
+ struct range_mutable_iterator<geometry::adapt::bp::holes_proxy<Polygon> >
+ {
+ typedef typename geometry::adapt::bp::holes_proxy<Polygon>::iterator_type type;
+ };
+
+ template<typename Polygon>
+ struct range_const_iterator<geometry::adapt::bp::holes_proxy<Polygon> >
+ {
+ typedef typename geometry::adapt::bp::holes_proxy<Polygon const>::iterator_type type;
+ };
+
+} // namespace boost
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_HOLES_PROXY_HPP
diff --git a/src/boost/geometry/geometries/adapted/boost_polygon/point.hpp b/src/boost/geometry/geometries/adapted/boost_polygon/point.hpp
new file mode 100644
index 0000000..2aabb56
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_polygon/point.hpp
@@ -0,0 +1,102 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POINT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POINT_HPP
+
+// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
+// boost::polygon::point_data -> boost::geometry::point
+
+
+#include <boost/polygon/polygon.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+
+template <typename CoordinateType>
+struct tag<boost::polygon::point_data<CoordinateType> >
+{
+ typedef point_tag type;
+};
+
+
+template <typename CoordinateType>
+struct coordinate_type<boost::polygon::point_data<CoordinateType> >
+{
+ typedef CoordinateType type;
+};
+
+
+template <typename CoordinateType>
+struct coordinate_system<boost::polygon::point_data<CoordinateType> >
+{
+ typedef cs::cartesian type;
+};
+
+
+template <typename CoordinateType>
+struct dimension<boost::polygon::point_data<CoordinateType> >
+ : boost::mpl::int_<2>
+{};
+
+
+template <typename CoordinateType>
+struct access<boost::polygon::point_data<CoordinateType>, 0>
+{
+ typedef boost::polygon::point_data<CoordinateType> point_type;
+
+ static inline CoordinateType get(point_type const& p)
+ {
+ return p.x();
+ }
+
+ static inline void set(point_type& p, CoordinateType const& value)
+ {
+ p.x(value);
+ }
+};
+
+
+template <typename CoordinateType>
+struct access<boost::polygon::point_data<CoordinateType>, 1>
+{
+ typedef boost::polygon::point_data<CoordinateType> point_type;
+
+ static inline CoordinateType get(point_type const& p)
+ {
+ return p.y();
+ }
+
+ static inline void set(point_type& p, CoordinateType const& value)
+ {
+ p.y(value);
+ }
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POINT_HPP
diff --git a/src/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp b/src/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp
new file mode 100644
index 0000000..5703601
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_polygon/polygon.hpp
@@ -0,0 +1,111 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POLYGON_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POLYGON_HPP
+
+// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
+// boost::polygon::polygon_with_holes_data -> boost::geometry::polygon
+
+#include <boost/polygon/polygon.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+
+#include <boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp>
+#include <boost/geometry/geometries/adapted/boost_polygon/hole_iterator.hpp>
+#include <boost/geometry/geometries/adapted/boost_polygon/holes_proxy.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType>
+struct tag<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+ typedef polygon_tag type;
+};
+
+template <typename CoordinateType>
+struct ring_const_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+ typedef adapt::bp::ring_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> const> type;
+};
+
+template <typename CoordinateType>
+struct ring_mutable_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+ typedef adapt::bp::ring_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> > type;
+};
+
+template <typename CoordinateType>
+struct interior_const_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+ typedef adapt::bp::holes_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> const> type;
+};
+
+template <typename CoordinateType>
+struct interior_mutable_type<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+ typedef adapt::bp::holes_proxy<boost::polygon::polygon_with_holes_data<CoordinateType> > type;
+};
+
+
+template <typename CoordinateType>
+struct exterior_ring<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+ typedef boost::polygon::polygon_with_holes_data<CoordinateType> polygon_type;
+ typedef adapt::bp::ring_proxy<polygon_type> proxy;
+ typedef adapt::bp::ring_proxy<polygon_type const> const_proxy;
+
+ static inline proxy get(polygon_type& p)
+ {
+ return proxy(p);
+ }
+
+ static inline const_proxy get(polygon_type const& p)
+ {
+ return const_proxy(p);
+ }
+};
+
+template <typename CoordinateType>
+struct interior_rings<boost::polygon::polygon_with_holes_data<CoordinateType> >
+{
+ typedef boost::polygon::polygon_with_holes_data<CoordinateType> polygon_type;
+ typedef adapt::bp::holes_proxy<polygon_type> proxy;
+ typedef adapt::bp::holes_proxy<polygon_type const> const_proxy;
+
+ static inline proxy get(polygon_type& p)
+ {
+ return proxy(p);
+ }
+
+ static inline const_proxy get(polygon_type const& p)
+ {
+ return const_proxy(p);
+ }
+};
+
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_POLYGON_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_polygon/ring.hpp b/src/boost/geometry/geometries/adapted/boost_polygon/ring.hpp
new file mode 100644
index 0000000..93b21fe
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_polygon/ring.hpp
@@ -0,0 +1,163 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_HPP
+
+// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
+// boost::polygon::polygon_data -> boost::geometry::ring
+
+#include <cstddef>
+#include <boost/polygon/polygon.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+template <typename CoordinateType>
+struct tag<boost::polygon::polygon_data<CoordinateType> >
+{
+ typedef ring_tag type;
+};
+
+template <typename CoordinateType>
+struct clear<boost::polygon::polygon_data<CoordinateType> >
+{
+ static inline void apply(boost::polygon::polygon_data<CoordinateType>& data)
+ {
+ // There is no "clear" function but we can assign
+ // a newly (and therefore empty) constructed polygon
+ boost::polygon::assign(data, boost::polygon::polygon_data<CoordinateType>());
+ }
+};
+
+template <typename CoordinateType>
+struct push_back<boost::polygon::polygon_data<CoordinateType> >
+{
+ typedef boost::polygon::point_data<CoordinateType> point_type;
+
+ static inline void apply(boost::polygon::polygon_data<CoordinateType>& data,
+ point_type const& point)
+ {
+ // Boost.Polygon's polygons are not appendable. So create a temporary vector,
+ // add a record and set it to the original. Of course: this is not efficient.
+ // But there seems no other way (without using a wrapper)
+ std::vector<point_type> temporary_vector
+ (
+ boost::polygon::begin_points(data),
+ boost::polygon::end_points(data)
+ );
+ temporary_vector.push_back(point);
+ data.set(temporary_vector.begin(), temporary_vector.end());
+ }
+};
+
+
+
+
+} // namespace traits
+
+}} // namespace boost::geometry
+
+
+// Adapt Boost.Polygon's polygon_data to Boost.Range
+// This just translates to
+// polygon_data.begin() and polygon_data.end()
+namespace boost
+{
+ template<typename CoordinateType>
+ struct range_mutable_iterator<boost::polygon::polygon_data<CoordinateType> >
+ {
+ typedef typename boost::polygon::polygon_traits
+ <
+ boost::polygon::polygon_data<CoordinateType>
+ >::iterator_type type;
+ };
+
+ template<typename CoordinateType>
+ struct range_const_iterator<boost::polygon::polygon_data<CoordinateType> >
+ {
+ typedef typename boost::polygon::polygon_traits
+ <
+ boost::polygon::polygon_data<CoordinateType>
+ >::iterator_type type;
+ };
+
+ template<typename CoordinateType>
+ struct range_size<boost::polygon::polygon_data<CoordinateType> >
+ {
+ typedef std::size_t type;
+ };
+
+} // namespace boost
+
+
+// Support Boost.Polygon's polygon_data for Boost.Range ADP
+namespace boost { namespace polygon
+{
+
+template<typename CoordinateType>
+inline typename polygon_traits
+ <
+ polygon_data<CoordinateType>
+ >::iterator_type range_begin(polygon_data<CoordinateType>& polygon)
+{
+ return polygon.begin();
+}
+
+template<typename CoordinateType>
+inline typename polygon_traits
+ <
+ polygon_data<CoordinateType>
+ >::iterator_type range_begin(polygon_data<CoordinateType> const& polygon)
+{
+ return polygon.begin();
+}
+
+template<typename CoordinateType>
+inline typename polygon_traits
+ <
+ polygon_data<CoordinateType>
+ >::iterator_type range_end(polygon_data<CoordinateType>& polygon)
+{
+ return polygon.end();
+}
+
+template<typename CoordinateType>
+inline typename polygon_traits
+ <
+ polygon_data<CoordinateType>
+ >::iterator_type range_end(polygon_data<CoordinateType> const& polygon)
+{
+ return polygon.end();
+}
+
+template<typename CoordinateType>
+inline std::size_t range_calculate_size(polygon_data<CoordinateType> const& polygon)
+{
+ return polygon.size();
+}
+
+}}
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_HPP
diff --git a/src/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp b/src/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
new file mode 100644
index 0000000..825ef80
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
@@ -0,0 +1,301 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
+
+// Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
+// boost::polygon::polygon_with_holes_data -> boost::geometry::polygon
+// pair{begin_points, end_points} -> ring_proxy
+
+#include <boost/polygon/polygon.hpp>
+#include <boost/range.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+namespace adapt { namespace bp
+{
+
+namespace detail
+{
+
+template <bool Mutable>
+struct modify
+{};
+
+template <>
+struct modify<true>
+{
+ template <typename Ring, typename Point>
+ static inline void push_back(Ring& ring, Point const& point)
+ {
+ // Boost.Polygon's polygons are not appendable. So create a temporary vector,
+ // add a record and set it to the original. Of course: this is not efficient.
+ // But there seems no other way (without using a wrapper)
+ std::vector<Point> temporary_vector
+ (
+ boost::polygon::begin_points(ring),
+ boost::polygon::end_points(ring)
+ );
+ temporary_vector.push_back(point);
+ boost::polygon::set_points(ring, temporary_vector.begin(), temporary_vector.end());
+ }
+
+};
+
+template <>
+struct modify<false>
+{
+ template <typename Ring, typename Point>
+ static inline void push_back(Ring& ring, Point const& point)
+ {
+ }
+
+};
+
+
+}
+
+
+// Polygon should implement the boost::polygon::polygon_with_holes_concept
+// Specify constness in the template parameter if necessary
+template<typename Polygon>
+class ring_proxy
+{
+public :
+ typedef typename boost::polygon::polygon_traits
+ <
+ typename boost::remove_const<Polygon>::type
+ >::iterator_type iterator_type;
+
+ typedef typename boost::polygon::polygon_with_holes_traits
+ <
+ typename boost::remove_const<Polygon>::type
+ >::iterator_holes_type hole_iterator_type;
+
+ static const bool is_mutable = !boost::is_const<Polygon>::type::value;
+
+ inline ring_proxy(Polygon& p)
+ : m_polygon_pointer(&p)
+ , m_do_hole(false)
+ {}
+
+ // Constructor used from hole_iterator
+ inline ring_proxy(Polygon& p, hole_iterator_type hole_it)
+ : m_polygon_pointer(&p)
+ , m_do_hole(true)
+ , m_hole_it(hole_it)
+ {}
+
+ // Default constructor, for mutable polygons / appending (interior) rings
+ inline ring_proxy()
+ : m_polygon_pointer(&m_polygon_for_default_constructor)
+ , m_do_hole(false)
+ {}
+
+
+ iterator_type begin() const
+ {
+ return m_do_hole
+ ? boost::polygon::begin_points(*m_hole_it)
+ : boost::polygon::begin_points(*m_polygon_pointer)
+ ;
+ }
+
+ iterator_type begin()
+ {
+ return m_do_hole
+ ? boost::polygon::begin_points(*m_hole_it)
+ : boost::polygon::begin_points(*m_polygon_pointer)
+ ;
+ }
+
+ iterator_type end() const
+ {
+ return m_do_hole
+ ? boost::polygon::end_points(*m_hole_it)
+ : boost::polygon::end_points(*m_polygon_pointer)
+ ;
+ }
+
+ iterator_type end()
+ {
+ return m_do_hole
+ ? boost::polygon::end_points(*m_hole_it)
+ : boost::polygon::end_points(*m_polygon_pointer)
+ ;
+ }
+
+ // Mutable
+ void clear()
+ {
+ Polygon p;
+ if (m_do_hole)
+ {
+ // Does NOT work see comment above
+ }
+ else
+ {
+ boost::polygon::set_points(*m_polygon_pointer,
+ boost::polygon::begin_points(p),
+ boost::polygon::end_points(p));
+ }
+ }
+
+ void resize(std::size_t new_size)
+ {
+ if (m_do_hole)
+ {
+ // Does NOT work see comment above
+ }
+ else
+ {
+ // TODO: implement this by resizing the container
+ }
+ }
+
+
+
+ template <typename Point>
+ void push_back(Point const& point)
+ {
+ if (m_do_hole)
+ {
+ //detail::modify<is_mutable>::push_back(*m_hole_it, point);
+ //std::cout << "HOLE: " << typeid(*m_hole_it).name() << std::endl;
+ //std::cout << "HOLE: " << typeid(m_hole_it).name() << std::endl;
+ //std::cout << "HOLE: " << typeid(hole_iterator_type).name() << std::endl;
+
+ // Note, ths does NOT work because hole_iterator_type is defined
+ // as a const_iterator by Boost.Polygon
+
+ }
+ else
+ {
+ detail::modify<is_mutable>::push_back(*m_polygon_pointer, point);
+ }
+ }
+
+private :
+ Polygon* m_polygon_pointer;
+ bool m_do_hole;
+ hole_iterator_type m_hole_it;
+
+ Polygon m_polygon_for_default_constructor;
+};
+
+
+
+
+// Support geometry::adapt::bp::ring_proxy for Boost.Range ADP
+template<typename Polygon>
+inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
+ range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
+{
+ return proxy.begin();
+}
+
+template<typename Polygon>
+inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
+ range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
+{
+ return proxy.begin();
+}
+
+template<typename Polygon>
+inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
+ range_end(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
+{
+ return proxy.end();
+}
+
+template<typename Polygon>
+inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
+ range_end(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
+{
+ return proxy.end();
+}
+
+
+
+
+}} // namespace adapt::bp
+
+
+namespace traits
+{
+
+template <typename Polygon>
+struct tag<adapt::bp::ring_proxy<Polygon> >
+{
+ typedef ring_tag type;
+};
+
+
+template <typename Polygon>
+struct rvalue_type<adapt::bp::ring_proxy<Polygon> >
+{
+ typedef adapt::bp::ring_proxy<Polygon> type;
+};
+
+template <typename Polygon>
+struct clear<adapt::bp::ring_proxy<Polygon> >
+{
+ static inline void apply(adapt::bp::ring_proxy<Polygon> proxy)
+ {
+ proxy.clear();
+ }
+};
+
+
+template <typename Polygon>
+struct resize<adapt::bp::ring_proxy<Polygon> >
+{
+ static inline void apply(adapt::bp::ring_proxy<Polygon> proxy, std::size_t new_size)
+ {
+ proxy.resize(new_size);
+ }
+};
+
+template <typename Polygon>
+struct push_back<adapt::bp::ring_proxy<Polygon> >
+{
+ static inline void apply(adapt::bp::ring_proxy<Polygon> proxy,
+ typename boost::polygon::polygon_traits<Polygon>::point_type const& point)
+ {
+ proxy.push_back(point);
+ }
+};
+
+
+} // namespace traits
+
+}} // namespace boost::geometry
+
+// Specialize ring_proxy for Boost.Range
+namespace boost
+{
+ template<typename Polygon>
+ struct range_mutable_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
+ {
+ typedef typename geometry::adapt::bp::ring_proxy<Polygon>::iterator_type type;
+ };
+
+ template<typename Polygon>
+ struct range_const_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
+ {
+ typedef typename geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type type;
+ };
+
+} // namespace boost
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
diff --git a/src/boost/geometry/geometries/adapted/boost_range/adjacent_filtered.hpp b/src/boost/geometry/geometries/adapted/boost_range/adjacent_filtered.hpp
new file mode 100644
index 0000000..496dbea
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_range/adjacent_filtered.hpp
@@ -0,0 +1,40 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_ADJACENT_FILTERED_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_ADJACENT_FILTERED_HPP
+
+
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+template<typename Filter, typename Geometry, bool DefaultPass>
+#if BOOST_VERSION > 104500
+struct tag<boost::adjacent_filtered_range<Filter, Geometry, DefaultPass> >
+#else
+struct tag<boost::range_detail::adjacent_filter_range<Filter, Geometry, DefaultPass> >
+#endif
+{
+ typedef typename geometry::tag<Geometry>::type type;
+};
+
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_ADJACENT_FILTERED_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_range/filtered.hpp b/src/boost/geometry/geometries/adapted/boost_range/filtered.hpp
new file mode 100644
index 0000000..990d608
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_range/filtered.hpp
@@ -0,0 +1,40 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_FILTERED_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_FILTERED_HPP
+
+
+#include <boost/range/adaptor/filtered.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+template<typename Filter, typename Geometry>
+#if BOOST_VERSION > 104500
+struct tag<boost::filtered_range<Filter, Geometry> >
+#else
+struct tag<boost::range_detail::filter_range<Filter, Geometry> >
+#endif
+{
+ typedef typename geometry::tag<Geometry>::type type;
+};
+
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_FILTERED_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_range/reversed.hpp b/src/boost/geometry/geometries/adapted/boost_range/reversed.hpp
new file mode 100644
index 0000000..3c8601f
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_range/reversed.hpp
@@ -0,0 +1,40 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_REVERSED_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_REVERSED_HPP
+
+
+#include <boost/range/adaptor/reversed.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+template<typename Geometry>
+#if BOOST_VERSION > 104500
+struct tag<boost::reversed_range<Geometry> >
+#else
+struct tag<boost::range_detail::reverse_range<Geometry> >
+#endif
+{
+ typedef typename geometry::tag<Geometry>::type type;
+};
+
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_REVERSED_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_range/sliced.hpp b/src/boost/geometry/geometries/adapted/boost_range/sliced.hpp
new file mode 100644
index 0000000..7018981
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_range/sliced.hpp
@@ -0,0 +1,36 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_SLICED_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_SLICED_HPP
+
+
+#include <boost/range/adaptor/sliced.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+template<typename Geometry>
+struct tag<boost::adaptors::sliced_range<Geometry> >
+{
+ typedef typename geometry::tag<Geometry>::type type;
+};
+
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_SLICED_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_range/strided.hpp b/src/boost/geometry/geometries/adapted/boost_range/strided.hpp
new file mode 100644
index 0000000..5c9cdd6
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_range/strided.hpp
@@ -0,0 +1,36 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_STRIDED_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_STRIDED_HPP
+
+
+#include <boost/range/adaptor/strided.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+template<typename Geometry>
+struct tag<boost::strided_range<Geometry> >
+{
+ typedef typename geometry::tag<Geometry>::type type;
+};
+
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_STRIDED_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_range/uniqued.hpp b/src/boost/geometry/geometries/adapted/boost_range/uniqued.hpp
new file mode 100644
index 0000000..beb51fe
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_range/uniqued.hpp
@@ -0,0 +1,40 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_UNIQUED_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_UNIQUED_HPP
+
+
+#include <boost/range/adaptor/uniqued.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace traits
+{
+
+template<typename Geometry>
+#if BOOST_VERSION > 104500
+struct tag<boost::uniqued_range<Geometry> >
+#else
+struct tag<boost::range_detail::unique_range<Geometry> >
+#endif
+{
+ typedef typename geometry::tag<Geometry>::type type;
+};
+
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_RANGE_UNIQUED_HPP
+
diff --git a/src/boost/geometry/geometries/adapted/boost_tuple.hpp b/src/boost/geometry/geometries/adapted/boost_tuple.hpp
new file mode 100644
index 0000000..58065fe
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/boost_tuple.hpp
@@ -0,0 +1,109 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_TUPLE_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_TUPLE_HPP
+
+
+#include <cstddef>
+
+#include <boost/tuple/tuple.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+struct tag<boost::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> >
+{
+ typedef point_tag type;
+};
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+struct coordinate_type<boost::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> >
+{
+ typedef T1 type;
+};
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+struct dimension<boost::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> >
+ : boost::mpl::int_
+ <
+ boost::tuples::length
+ <
+ boost::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
+ >::value
+ >
+{};
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ std::size_t Dimension>
+struct access
+ <
+ boost::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>,
+ Dimension
+ >
+{
+ static inline T1 get(
+ boost::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> const& point)
+ {
+ return point.template get<Dimension>();
+ }
+
+ static inline void set(
+ boost::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& point,
+ T1 const& value)
+ {
+ point.template get<Dimension>() = value;
+ }
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+// Convenience registration macro to bind boost::tuple to a CS
+#define BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(CoordinateSystem) \
+ namespace boost { namespace geometry { namespace traits { \
+ template <typename T1, typename T2, typename T3, typename T4, typename T5, \
+ typename T6, typename T7, typename T8, typename T9, typename T10> \
+ struct coordinate_system<boost::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> > \
+ { \
+ typedef CoordinateSystem type; \
+ }; \
+ }}}
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_TUPLE_HPP
diff --git a/src/boost/geometry/geometries/adapted/c_array.hpp b/src/boost/geometry/geometries/adapted/c_array.hpp
new file mode 100644
index 0000000..1b4523d
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/c_array.hpp
@@ -0,0 +1,111 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_C_ARRAY_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_C_ARRAY_HPP
+
+#include <cstddef>
+
+#include <boost/type_traits/is_arithmetic.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+// Create class and specialization to indicate the tag
+// for normal cases and the case that the type of the c-array is arithmetic
+template <bool>
+struct c_array_tag
+{
+ typedef geometry_not_recognized_tag type;
+};
+
+
+template <>
+struct c_array_tag<true>
+{
+ typedef point_tag type;
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+// Assign the point-tag, preventing arrays of points getting a point-tag
+template <typename CoordinateType, std::size_t DimensionCount>
+struct tag<CoordinateType[DimensionCount]>
+ : detail::c_array_tag<boost::is_arithmetic<CoordinateType>::value> {};
+
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct coordinate_type<CoordinateType[DimensionCount]>
+{
+ typedef CoordinateType type;
+};
+
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct dimension<CoordinateType[DimensionCount]>: boost::mpl::int_<DimensionCount> {};
+
+
+template <typename CoordinateType, std::size_t DimensionCount, std::size_t Dimension>
+struct access<CoordinateType[DimensionCount], Dimension>
+{
+ static inline CoordinateType get(CoordinateType const p[DimensionCount])
+ {
+ return p[Dimension];
+ }
+
+ static inline void set(CoordinateType p[DimensionCount],
+ CoordinateType const& value)
+ {
+ p[Dimension] = value;
+ }
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#define BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(CoordinateSystem) \
+ namespace boost { namespace geometry { namespace traits { \
+ template <typename T, std::size_t N> \
+ struct coordinate_system<T[N]> \
+ { \
+ typedef CoordinateSystem type; \
+ }; \
+ }}}
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_C_ARRAY_HPP
diff --git a/src/boost/geometry/geometries/adapted/std_pair_as_segment.hpp b/src/boost/geometry/geometries/adapted/std_pair_as_segment.hpp
new file mode 100644
index 0000000..e9200e0
--- /dev/null
+++ b/src/boost/geometry/geometries/adapted/std_pair_as_segment.hpp
@@ -0,0 +1,98 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_STD_PAIR_AS_SEGMENT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_STD_PAIR_AS_SEGMENT_HPP
+
+// Only possible if the std::pair is not used for iterator/pair
+// (maybe it is possible to avoid that by detecting in the other file
+// if an iterator was used in the pair)
+
+#ifdef BOOST_GEOMETRY_ADAPTED_STD_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted std:: containers or iterator pair
+#endif
+
+#define BOOST_GEOMETRY_ADAPTED_STD_RANGE_TAG_DEFINED
+
+
+#include <cstddef>
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+
+template <typename Point>
+struct tag<std::pair<Point, Point> >
+{
+ typedef segment_tag type;
+};
+
+template <typename Point>
+struct point_type<std::pair<Point, Point> >
+{
+ typedef Point type;
+};
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<std::pair<Point, Point>, 0, Dimension>
+{
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+
+ static inline coordinate_type get(std::pair<Point, Point> const& s)
+ {
+ return geometry::get<Dimension>(s.first);
+ }
+
+ static inline void set(std::pair<Point, Point>& s, coordinate_type const& value)
+ {
+ geometry::set<Dimension>(s.first, value);
+ }
+};
+
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<std::pair<Point, Point>, 1, Dimension>
+{
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+
+ static inline coordinate_type get(std::pair<Point, Point> const& s)
+ {
+ return geometry::get<Dimension>(s.second);
+ }
+
+ static inline void set(std::pair<Point, Point>& s, coordinate_type const& value)
+ {
+ geometry::set<Dimension>(s.second, value);
+ }
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_STD_PAIR_AS_SEGMENT_HPP
diff --git a/src/boost/geometry/geometries/box.hpp b/src/boost/geometry/geometries/box.hpp
new file mode 100644
index 0000000..a2e3d4f
--- /dev/null
+++ b/src/boost/geometry/geometries/box.hpp
@@ -0,0 +1,134 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_BOX_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_BOX_HPP
+
+#include <cstddef>
+
+#include <boost/concept/assert.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+
+/*!
+ \brief Class box: defines a box made of two describing points
+ \ingroup geometries
+ \details Box is always described by a min_corner() and a max_corner() point. If another
+ rectangle is used, use linear_ring or polygon.
+ \note Boxes are for selections and for calculating the envelope of geometries. Not all algorithms
+ are implemented for box. Boxes are also used in Spatial Indexes.
+ \tparam Point point type. The box takes a point type as template parameter.
+ The point type can be any point type.
+ It can be 2D but can also be 3D or more dimensional.
+ The box can also take a latlong point type as template parameter.
+ */
+
+template<typename Point>
+class box
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+public:
+
+ inline box() {}
+
+ /*!
+ \brief Constructor taking the minimum corner point and the maximum corner point
+ */
+ inline box(Point const& min_corner, Point const& max_corner)
+ {
+ geometry::convert(min_corner, m_min_corner);
+ geometry::convert(max_corner, m_max_corner);
+ }
+
+ inline Point const& min_corner() const { return m_min_corner; }
+ inline Point const& max_corner() const { return m_max_corner; }
+
+ inline Point& min_corner() { return m_min_corner; }
+ inline Point& max_corner() { return m_max_corner; }
+
+private:
+
+ Point m_min_corner;
+ Point m_max_corner;
+};
+
+
+} // namespace model
+
+
+// Traits specializations for box above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename Point>
+struct tag<model::box<Point> >
+{
+ typedef box_tag type;
+};
+
+template <typename Point>
+struct point_type<model::box<Point> >
+{
+ typedef Point type;
+};
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<model::box<Point>, min_corner, Dimension>
+{
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+
+ static inline coordinate_type get(model::box<Point> const& b)
+ {
+ return geometry::get<Dimension>(b.min_corner());
+ }
+
+ static inline void set(model::box<Point>& b, coordinate_type const& value)
+ {
+ geometry::set<Dimension>(b.min_corner(), value);
+ }
+};
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<model::box<Point>, max_corner, Dimension>
+{
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+
+ static inline coordinate_type get(model::box<Point> const& b)
+ {
+ return geometry::get<Dimension>(b.max_corner());
+ }
+
+ static inline void set(model::box<Point>& b, coordinate_type const& value)
+ {
+ geometry::set<Dimension>(b.max_corner(), value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_BOX_HPP
diff --git a/src/boost/geometry/geometries/concepts/box_concept.hpp b/src/boost/geometry/geometries/concepts/box_concept.hpp
new file mode 100644
index 0000000..ea0d84c
--- /dev/null
+++ b/src/boost/geometry/geometries/concepts/box_concept.hpp
@@ -0,0 +1,136 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_BOX_CONCEPT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_BOX_CONCEPT_HPP
+
+
+#include <cstddef>
+
+#include <boost/concept_check.hpp>
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+\brief Box concept
+\ingroup concepts
+\par Formal definition:
+The box concept is defined as following:
+- there must be a specialization of traits::tag defining box_tag as type
+- there must be a specialization of traits::point_type to define the
+ underlying point type (even if it does not consist of points, it should define
+ this type, to indicate the points it can work with)
+- there must be a specialization of traits::indexed_access, per index
+ (min_corner, max_corner) and per dimension, with two functions:
+ - get to get a coordinate value
+ - set to set a coordinate value (this one is not checked for ConstBox)
+*/
+template <typename Geometry>
+class Box
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename point_type<Geometry>::type point_type;
+
+
+ template
+ <
+ std::size_t Index,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+ >
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ Geometry* b = 0;
+ geometry::set<Index, Dimension>(*b, geometry::get<Index, Dimension>(*b));
+ dimension_checker<Index, Dimension + 1, DimensionCount>::apply();
+ }
+ };
+
+ template <std::size_t Index, std::size_t DimensionCount>
+ struct dimension_checker<Index, DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public :
+ BOOST_CONCEPT_USAGE(Box)
+ {
+ static const std::size_t n = dimension<Geometry>::type::value;
+ dimension_checker<min_corner, 0, n>::apply();
+ dimension_checker<max_corner, 0, n>::apply();
+ }
+#endif
+};
+
+
+/*!
+\brief Box concept (const version)
+\ingroup const_concepts
+\details The ConstBox concept apply the same as the Box concept,
+but does not apply write access.
+*/
+template <typename Geometry>
+class ConstBox
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename coordinate_type<Geometry>::type coordinate_type;
+
+ template
+ <
+ std::size_t Index,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+ >
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ const Geometry* b = 0;
+ coordinate_type coord(geometry::get<Index, Dimension>(*b));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker<Index, Dimension + 1, DimensionCount>::apply();
+ }
+ };
+
+ template <std::size_t Index, std::size_t DimensionCount>
+ struct dimension_checker<Index, DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public :
+ BOOST_CONCEPT_USAGE(ConstBox)
+ {
+ static const std::size_t n = dimension<Geometry>::type::value;
+ dimension_checker<min_corner, 0, n>::apply();
+ dimension_checker<max_corner, 0, n>::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_BOX_CONCEPT_HPP
diff --git a/src/boost/geometry/geometries/concepts/check.hpp b/src/boost/geometry/geometries/concepts/check.hpp
new file mode 100644
index 0000000..f8001f0
--- /dev/null
+++ b/src/boost/geometry/geometries/concepts/check.hpp
@@ -0,0 +1,171 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_CHECK_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_CHECK_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/concept/requires.hpp>
+
+#include <boost/type_traits/is_const.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+
+#include <boost/geometry/geometries/concepts/box_concept.hpp>
+#include <boost/geometry/geometries/concepts/linestring_concept.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/geometries/concepts/polygon_concept.hpp>
+#include <boost/geometry/geometries/concepts/ring_concept.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace concept_check
+{
+
+template <typename Concept>
+class check
+{
+ BOOST_CONCEPT_ASSERT((Concept ));
+};
+
+}} // namespace detail::concept_check
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename Geometry, bool IsConst>
+struct check
+{};
+
+
+template <typename Geometry>
+struct check<point_tag, Geometry, true>
+ : detail::concept_check::check<concept::ConstPoint<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<point_tag, Geometry, false>
+ : detail::concept_check::check<concept::Point<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<linestring_tag, Geometry, true>
+ : detail::concept_check::check<concept::ConstLinestring<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<linestring_tag, Geometry, false>
+ : detail::concept_check::check<concept::Linestring<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<polygon_tag, Geometry, true>
+ : detail::concept_check::check<concept::ConstPolygon<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<polygon_tag, Geometry, false>
+ : detail::concept_check::check<concept::Polygon<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<box_tag, Geometry, true>
+ : detail::concept_check::check<concept::ConstBox<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<box_tag, Geometry, false>
+ : detail::concept_check::check<concept::Box<Geometry> >
+{};
+
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+namespace concept
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename Geometry, bool IsConst>
+struct checker : dispatch::check
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ IsConst
+ >
+{};
+
+
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+ \brief Checks, in compile-time, the concept of any geometry
+ \ingroup concepts
+*/
+template <typename Geometry>
+inline void check()
+{
+ detail::checker<Geometry, boost::is_const<Geometry>::type::value> c;
+ boost::ignore_unused_variable_warning(c);
+}
+
+
+/*!
+ \brief Checks, in compile-time, the concept of two geometries, and if they
+ have equal dimensions
+ \ingroup concepts
+*/
+template <typename Geometry1, typename Geometry2>
+inline void check_concepts_and_equal_dimensions()
+{
+ check<Geometry1>();
+ check<Geometry2>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+}
+
+
+} // namespace concept
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_CHECK_HPP
diff --git a/src/boost/geometry/geometries/concepts/linestring_concept.hpp b/src/boost/geometry/geometries/concepts/linestring_concept.hpp
new file mode 100644
index 0000000..091336f
--- /dev/null
+++ b/src/boost/geometry/geometries/concepts/linestring_concept.hpp
@@ -0,0 +1,125 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_LINESTRING_CONCEPT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_LINESTRING_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+\brief Linestring concept
+\ingroup concepts
+\par Formal definition:
+The linestring concept is defined as following:
+- there must be a specialization of traits::tag defining linestring_tag as type
+- it must behave like a Boost.Range
+- it must implement a std::back_insert_iterator
+ - either by implementing push_back
+ - or by specializing std::back_insert_iterator
+
+\note to fulfill the concepts, no traits class has to be specialized to
+define the point type.
+
+\par Example:
+
+A custom linestring, defining the necessary specializations to fulfill to the concept.
+
+Suppose that the following linestring is defined:
+\dontinclude doxygen_5.cpp
+\skip custom_linestring1
+\until };
+
+It can then be adapted to the concept as following:
+\dontinclude doxygen_5.cpp
+\skip adapt custom_linestring1
+\until }}
+
+\note
+- There is also the registration macro BOOST_GEOMETRY_REGISTER_LINESTRING
+- For registration of std::vector<P> (and deque, and list) it is enough to
+include the header-file geometries/adapted/std_as_linestring.hpp. That registers
+a vector as a linestring (so it cannot be registered as a linear ring then,
+in the same source code).
+
+
+*/
+
+template <typename Geometry>
+class Linestring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename point_type<Geometry>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+public :
+
+ BOOST_CONCEPT_USAGE(Linestring)
+ {
+ Geometry* ls = 0;
+ traits::clear<Geometry>::apply(*ls);
+ traits::resize<Geometry>::apply(*ls, 0);
+ point_type* point = 0;
+ traits::push_back<Geometry>::apply(*ls, *point);
+ }
+#endif
+};
+
+
+/*!
+\brief Linestring concept (const version)
+\ingroup const_concepts
+\details The ConstLinestring concept check the same as the Linestring concept,
+but does not check write access.
+*/
+template <typename Geometry>
+class ConstLinestring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename point_type<Geometry>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+ //BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+ // Relaxed the concept.
+ BOOST_CONCEPT_ASSERT( (boost::ForwardRangeConcept<Geometry>) );
+
+
+public :
+
+ BOOST_CONCEPT_USAGE(ConstLinestring)
+ {
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_LINESTRING_CONCEPT_HPP
diff --git a/src/boost/geometry/geometries/concepts/point_concept.hpp b/src/boost/geometry/geometries/concepts/point_concept.hpp
new file mode 100644
index 0000000..1e1b31e
--- /dev/null
+++ b/src/boost/geometry/geometries/concepts/point_concept.hpp
@@ -0,0 +1,176 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
+
+#include <cstddef>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+
+
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+/*!
+\brief Point concept.
+\ingroup concepts
+
+\par Formal definition:
+The point concept is defined as following:
+- there must be a specialization of traits::tag defining point_tag as type
+- there must be a specialization of traits::coordinate_type defining the type
+ of its coordinates
+- there must be a specialization of traits::coordinate_system defining its
+ coordinate system (cartesian, spherical, etc)
+- there must be a specialization of traits::dimension defining its number
+ of dimensions (2, 3, ...) (derive it conveniently
+ from boost::mpl::int_<X> for X-D)
+- there must be a specialization of traits::access, per dimension,
+ with two functions:
+ - \b get to get a coordinate value
+ - \b set to set a coordinate value (this one is not checked for ConstPoint)
+
+\par Example:
+
+A legacy point, defining the necessary specializations to fulfil to the concept.
+
+Suppose that the following point is defined:
+\dontinclude doxygen_5.cpp
+\skip legacy_point1
+\until };
+
+It can then be adapted to the concept as following:
+\dontinclude doxygen_5.cpp
+\skip adapt legacy_point1
+\until }}
+
+Note that it is done like above to show the system. Users will normally use the registration macro.
+
+\par Example:
+
+A read-only legacy point, using a macro to fulfil to the ConstPoint concept.
+It cannot be modified by the library but can be used in all algorithms where
+points are not modified.
+
+The point looks like the following:
+
+\dontinclude doxygen_5.cpp
+\skip legacy_point2
+\until };
+
+It uses the macro as following:
+\dontinclude doxygen_5.cpp
+\skip adapt legacy_point2
+\until end adaptation
+
+*/
+
+template <typename Geometry>
+class Point
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ typedef typename coordinate_type<Geometry>::type ctype;
+ typedef typename coordinate_system<Geometry>::type csystem;
+
+ enum { ccount = dimension<Geometry>::value };
+
+
+ template <typename P, std::size_t Dimension, std::size_t DimensionCount>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ P* p = 0;
+ geometry::set<Dimension>(*p, geometry::get<Dimension>(*p));
+ dimension_checker<P, Dimension+1, DimensionCount>::apply();
+ }
+ };
+
+
+ template <typename P, std::size_t DimensionCount>
+ struct dimension_checker<P, DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the Point concept
+ BOOST_CONCEPT_USAGE(Point)
+ {
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+
+/*!
+\brief point concept (const version).
+
+\ingroup const_concepts
+
+\details The ConstPoint concept apply the same as the Point concept,
+but does not apply write access.
+
+*/
+template <typename Geometry>
+class ConstPoint
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ typedef typename coordinate_type<Geometry>::type ctype;
+ typedef typename coordinate_system<Geometry>::type csystem;
+
+ enum { ccount = dimension<Geometry>::value };
+
+
+ template <typename P, std::size_t Dimension, std::size_t DimensionCount>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ const P* p = 0;
+ ctype coord(geometry::get<Dimension>(*p));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker<P, Dimension+1, DimensionCount>::apply();
+ }
+ };
+
+
+ template <typename P, std::size_t DimensionCount>
+ struct dimension_checker<P, DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the ConstPoint concept
+ BOOST_CONCEPT_USAGE(ConstPoint)
+ {
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
diff --git a/src/boost/geometry/geometries/concepts/polygon_concept.hpp b/src/boost/geometry/geometries/concepts/polygon_concept.hpp
new file mode 100644
index 0000000..b478a22
--- /dev/null
+++ b/src/boost/geometry/geometries/concepts/polygon_concept.hpp
@@ -0,0 +1,135 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POLYGON_CONCEPT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POLYGON_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/geometries/concepts/ring_concept.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+/*!
+\brief Checks polygon concept
+\ingroup concepts
+*/
+template <typename PolygonType>
+class Polygon
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename boost::remove_const<PolygonType>::type polygon_type;
+
+ typedef typename traits::ring_const_type<polygon_type>::type ring_const_type;
+ typedef typename traits::ring_mutable_type<polygon_type>::type ring_mutable_type;
+ typedef typename traits::interior_const_type<polygon_type>::type interior_const_type;
+ typedef typename traits::interior_mutable_type<polygon_type>::type interior_mutable_type;
+
+ typedef typename point_type<PolygonType>::type point_type;
+ typedef typename ring_type<PolygonType>::type ring_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+ BOOST_CONCEPT_ASSERT( (concept::Ring<ring_type>) );
+
+ //BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<interior_type>) );
+
+ struct checker
+ {
+ static inline void apply()
+ {
+ polygon_type* poly = 0;
+ polygon_type const* cpoly = poly;
+
+ ring_mutable_type e = traits::exterior_ring<PolygonType>::get(*poly);
+ interior_mutable_type i = traits::interior_rings<PolygonType>::get(*poly);
+ ring_const_type ce = traits::exterior_ring<PolygonType>::get(*cpoly);
+ interior_const_type ci = traits::interior_rings<PolygonType>::get(*cpoly);
+
+ boost::ignore_unused_variable_warning(e);
+ boost::ignore_unused_variable_warning(i);
+ boost::ignore_unused_variable_warning(ce);
+ boost::ignore_unused_variable_warning(ci);
+ boost::ignore_unused_variable_warning(poly);
+ boost::ignore_unused_variable_warning(cpoly);
+ }
+ };
+
+public:
+
+ BOOST_CONCEPT_USAGE(Polygon)
+ {
+ checker::apply();
+ }
+#endif
+};
+
+
+/*!
+\brief Checks polygon concept (const version)
+\ingroup const_concepts
+*/
+template <typename PolygonType>
+class ConstPolygon
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ typedef typename boost::remove_const<PolygonType>::type const_polygon_type;
+
+ typedef typename traits::ring_const_type<const_polygon_type>::type ring_const_type;
+ typedef typename traits::interior_const_type<const_polygon_type>::type interior_const_type;
+
+ typedef typename point_type<const_polygon_type>::type point_type;
+ typedef typename ring_type<const_polygon_type>::type ring_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstRing<ring_type>) );
+
+ ////BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<interior_type>) );
+
+ struct checker
+ {
+ static inline void apply()
+ {
+ const_polygon_type const* cpoly = 0;
+
+ ring_const_type ce = traits::exterior_ring<const_polygon_type>::get(*cpoly);
+ interior_const_type ci = traits::interior_rings<const_polygon_type>::get(*cpoly);
+
+ boost::ignore_unused_variable_warning(ce);
+ boost::ignore_unused_variable_warning(ci);
+ boost::ignore_unused_variable_warning(cpoly);
+ }
+ };
+
+public:
+
+ BOOST_CONCEPT_USAGE(ConstPolygon)
+ {
+ checker::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POLYGON_CONCEPT_HPP
diff --git a/src/boost/geometry/geometries/concepts/ring_concept.hpp b/src/boost/geometry/geometries/concepts/ring_concept.hpp
new file mode 100644
index 0000000..02a36c9
--- /dev/null
+++ b/src/boost/geometry/geometries/concepts/ring_concept.hpp
@@ -0,0 +1,99 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_RING_CONCEPT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_RING_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+\brief ring concept
+\ingroup concepts
+\par Formal definition:
+The ring concept is defined as following:
+- there must be a specialization of traits::tag defining ring_tag as type
+- it must behave like a Boost.Range
+- there can optionally be a specialization of traits::point_order defining the
+ order or orientation of its points, clockwise or counterclockwise.
+- it must implement a std::back_insert_iterator
+ (This is the same as the for the concept Linestring, and described there)
+
+\note to fulfill the concepts, no traits class has to be specialized to
+define the point type.
+*/
+template <typename Geometry>
+class Ring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename point_type<Geometry>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+public :
+
+ BOOST_CONCEPT_USAGE(Ring)
+ {
+ Geometry* ring = 0;
+ traits::clear<Geometry>::apply(*ring);
+ traits::resize<Geometry>::apply(*ring, 0);
+ point_type* point = 0;
+ traits::push_back<Geometry>::apply(*ring, *point);
+ }
+#endif
+};
+
+
+/*!
+\brief (linear) ring concept (const version)
+\ingroup const_concepts
+\details The ConstLinearRing concept check the same as the Geometry concept,
+but does not check write access.
+*/
+template <typename Geometry>
+class ConstRing
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename point_type<Geometry>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+ BOOST_CONCEPT_USAGE(ConstRing)
+ {
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_RING_CONCEPT_HPP
diff --git a/src/boost/geometry/geometries/concepts/segment_concept.hpp b/src/boost/geometry/geometries/concepts/segment_concept.hpp
new file mode 100644
index 0000000..8d2d300
--- /dev/null
+++ b/src/boost/geometry/geometries/concepts/segment_concept.hpp
@@ -0,0 +1,135 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_SEGMENT_CONCEPT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_SEGMENT_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+\brief Segment concept.
+\ingroup concepts
+\details Formal definition:
+The segment concept is defined as following:
+- there must be a specialization of traits::tag defining segment_tag as type
+- there must be a specialization of traits::point_type to define the
+ underlying point type (even if it does not consist of points, it should define
+ this type, to indicate the points it can work with)
+- there must be a specialization of traits::indexed_access, per index
+ and per dimension, with two functions:
+ - get to get a coordinate value
+ - set to set a coordinate value (this one is not checked for ConstSegment)
+
+\note The segment concept is similar to the box concept, defining another tag.
+However, the box concept assumes the index as min_corner, max_corner, while
+for the segment concept there is no assumption.
+*/
+template <typename Geometry>
+class Segment
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename point_type<Geometry>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+
+
+ template <size_t Index, size_t Dimension, size_t DimensionCount>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ Geometry* s = 0;
+ geometry::set<Index, Dimension>(*s, geometry::get<Index, Dimension>(*s));
+ dimension_checker<Index, Dimension + 1, DimensionCount>::apply();
+ }
+ };
+
+ template <size_t Index, size_t DimensionCount>
+ struct dimension_checker<Index, DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public :
+
+ BOOST_CONCEPT_USAGE(Segment)
+ {
+ static const size_t n = dimension<point_type>::type::value;
+ dimension_checker<0, 0, n>::apply();
+ dimension_checker<1, 0, n>::apply();
+ }
+#endif
+};
+
+
+/*!
+\brief Segment concept (const version).
+\ingroup const_concepts
+\details The ConstSegment concept verifies the same as the Segment concept,
+but does not verify write access.
+*/
+template <typename Geometry>
+class ConstSegment
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename coordinate_type<Geometry>::type coordinate_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+
+
+ template <size_t Index, size_t Dimension, size_t DimensionCount>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ const Geometry* s = 0;
+ coordinate_type coord(geometry::get<Index, Dimension>(*s));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker<Index, Dimension + 1, DimensionCount>::apply();
+ }
+ };
+
+ template <size_t Index, size_t DimensionCount>
+ struct dimension_checker<Index, DimensionCount, DimensionCount>
+ {
+ static void apply() {}
+ };
+
+public :
+
+ BOOST_CONCEPT_USAGE(ConstSegment)
+ {
+ static const size_t n = dimension<point_type>::type::value;
+ dimension_checker<0, 0, n>::apply();
+ dimension_checker<1, 0, n>::apply();
+ }
+#endif
+};
+
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_SEGMENT_CONCEPT_HPP
diff --git a/src/boost/geometry/geometries/geometries.hpp b/src/boost/geometry/geometries/geometries.hpp
new file mode 100644
index 0000000..cda55c1
--- /dev/null
+++ b/src/boost/geometry/geometries/geometries.hpp
@@ -0,0 +1,25 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_HPP
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/linestring.hpp>
+#include <boost/geometry/geometries/polygon.hpp>
+
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/ring.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_HPP
diff --git a/src/boost/geometry/geometries/linestring.hpp b/src/boost/geometry/geometries/linestring.hpp
new file mode 100644
index 0000000..38bc3d4
--- /dev/null
+++ b/src/boost/geometry/geometries/linestring.hpp
@@ -0,0 +1,95 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_LINESTRING_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_LINESTRING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+/*!
+\brief A linestring (named so by OGC) is a collection (default a vector) of points.
+\ingroup geometries
+\tparam Point \tparam_point
+\tparam Container \tparam_container
+\tparam Allocator \tparam_allocator
+
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_linestring Linestring Concept]
+}
+
+*/
+template
+<
+ typename Point,
+ template<typename,typename> class Container = std::vector,
+ template<typename> class Allocator = std::allocator
+>
+class linestring : public Container<Point, Allocator<Point> >
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ typedef Container<Point, Allocator<Point> > base_type;
+
+public :
+ /// \constructor_default{linestring}
+ inline linestring()
+ : base_type()
+ {}
+
+ /// \constructor_begin_end{linestring}
+ template <typename Iterator>
+ inline linestring(Iterator begin, Iterator end)
+ : base_type(begin, end)
+ {}
+};
+
+} // namespace model
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+ typename Point,
+ template<typename,typename> class Container,
+ template<typename> class Allocator
+>
+struct tag<model::linestring<Point, Container, Allocator> >
+{
+ typedef linestring_tag type;
+};
+} // namespace traits
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_LINESTRING_HPP
diff --git a/src/boost/geometry/geometries/point.hpp b/src/boost/geometry/geometries/point.hpp
new file mode 100644
index 0000000..b40a473
--- /dev/null
+++ b/src/boost/geometry/geometries/point.hpp
@@ -0,0 +1,178 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/int.hpp>
+#include <boost/static_assert.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/coordinate_system.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/util/math.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+namespace model
+{
+
+/*!
+\brief Basic point class, having coordinates defined in a neutral way
+\details Defines a neutral point class, fulfilling the Point Concept.
+ Library users can use this point class, or use their own point classes.
+ This point class is used in most of the samples and tests of Boost.Geometry
+ This point class is used occasionally within the library, where a temporary
+ point class is necessary.
+\ingroup geometries
+\tparam CoordinateType \tparam_numeric
+\tparam DimensionCount number of coordinates, usually 2 or 3
+\tparam CoordinateSystem coordinate system, for example cs::cartesian
+
+\qbk{[include reference/geometries/point.qbk]}
+\qbk{before.synopsis, [heading Model of]}
+\qbk{before.synopsis, [link geometry.reference.concepts.concept_point Point Concept]}
+
+
+*/
+template
+<
+ typename CoordinateType,
+ std::size_t DimensionCount,
+ typename CoordinateSystem
+>
+class point
+{
+public:
+
+ /// @brief Default constructor, no initialization
+ inline point()
+ {}
+
+ /// @brief Constructor to set one, two or three values
+ inline point(CoordinateType const& v0, CoordinateType const& v1 = 0, CoordinateType const& v2 = 0)
+ {
+ if (DimensionCount >= 1) m_values[0] = v0;
+ if (DimensionCount >= 2) m_values[1] = v1;
+ if (DimensionCount >= 3) m_values[2] = v2;
+ }
+
+ /// @brief Get a coordinate
+ /// @tparam K coordinate to get
+ /// @return the coordinate
+ template <std::size_t K>
+ inline CoordinateType const& get() const
+ {
+ BOOST_STATIC_ASSERT(K < DimensionCount);
+ return m_values[K];
+ }
+
+ /// @brief Set a coordinate
+ /// @tparam K coordinate to set
+ /// @param value value to set
+ template <std::size_t K>
+ inline void set(CoordinateType const& value)
+ {
+ BOOST_STATIC_ASSERT(K < DimensionCount);
+ m_values[K] = value;
+ }
+
+private:
+
+ CoordinateType m_values[DimensionCount];
+};
+
+
+} // namespace model
+
+// Adapt the point to the concept
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+template
+<
+ typename CoordinateType,
+ std::size_t DimensionCount,
+ typename CoordinateSystem
+>
+struct tag<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
+{
+ typedef point_tag type;
+};
+
+template
+<
+ typename CoordinateType,
+ std::size_t DimensionCount,
+ typename CoordinateSystem
+>
+struct coordinate_type<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
+{
+ typedef CoordinateType type;
+};
+
+template
+<
+ typename CoordinateType,
+ std::size_t DimensionCount,
+ typename CoordinateSystem
+>
+struct coordinate_system<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
+{
+ typedef CoordinateSystem type;
+};
+
+template
+<
+ typename CoordinateType,
+ std::size_t DimensionCount,
+ typename CoordinateSystem
+>
+struct dimension<model::point<CoordinateType, DimensionCount, CoordinateSystem> >
+ : boost::mpl::int_<DimensionCount>
+{};
+
+template
+<
+ typename CoordinateType,
+ std::size_t DimensionCount,
+ typename CoordinateSystem,
+ std::size_t Dimension
+>
+struct access<model::point<CoordinateType, DimensionCount, CoordinateSystem>, Dimension>
+{
+ static inline CoordinateType get(
+ model::point<CoordinateType, DimensionCount, CoordinateSystem> const& p)
+ {
+ return p.template get<Dimension>();
+ }
+
+ static inline void set(
+ model::point<CoordinateType, DimensionCount, CoordinateSystem>& p,
+ CoordinateType const& value)
+ {
+ p.template set<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_POINT_HPP
diff --git a/src/boost/geometry/geometries/point_xy.hpp b/src/boost/geometry/geometries/point_xy.hpp
new file mode 100644
index 0000000..6529306
--- /dev/null
+++ b/src/boost/geometry/geometries/point_xy.hpp
@@ -0,0 +1,128 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_POINT_XY_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_POINT_XY_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/int.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/geometries/point.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace model { namespace d2
+{
+
+/*!
+\brief 2D point in Cartesian coordinate system
+\tparam CoordinateType numeric type, for example, double, float, int
+\tparam CoordinateSystem coordinate system, defaults to cs::cartesian
+
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_point Point Concept]
+}
+
+\qbk{[include reference/geometries/point_assign_warning.qbk]}
+
+*/
+template<typename CoordinateType, typename CoordinateSystem = cs::cartesian>
+class point_xy : public model::point<CoordinateType, 2, CoordinateSystem>
+{
+public:
+
+ /// Default constructor, does not initialize anything
+ inline point_xy()
+ : model::point<CoordinateType, 2, CoordinateSystem>()
+ {}
+
+ /// Constructor with x/y values
+ inline point_xy(CoordinateType const& x, CoordinateType const& y)
+ : model::point<CoordinateType, 2, CoordinateSystem>(x, y)
+ {}
+
+ /// Get x-value
+ inline CoordinateType const& x() const
+ { return this->template get<0>(); }
+
+ /// Get y-value
+ inline CoordinateType const& y() const
+ { return this->template get<1>(); }
+
+ /// Set x-value
+ inline void x(CoordinateType const& v)
+ { this->template set<0>(v); }
+
+ /// Set y-value
+ inline void y(CoordinateType const& v)
+ { this->template set<1>(v); }
+};
+
+
+}} // namespace model::d2
+
+
+// Adapt the point_xy to the concept
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType, typename CoordinateSystem>
+struct tag<model::d2::point_xy<CoordinateType, CoordinateSystem> >
+{
+ typedef point_tag type;
+};
+
+template<typename CoordinateType, typename CoordinateSystem>
+struct coordinate_type<model::d2::point_xy<CoordinateType, CoordinateSystem> >
+{
+ typedef CoordinateType type;
+};
+
+template<typename CoordinateType, typename CoordinateSystem>
+struct coordinate_system<model::d2::point_xy<CoordinateType, CoordinateSystem> >
+{
+ typedef CoordinateSystem type;
+};
+
+template<typename CoordinateType, typename CoordinateSystem>
+struct dimension<model::d2::point_xy<CoordinateType, CoordinateSystem> >
+ : boost::mpl::int_<2>
+{};
+
+template<typename CoordinateType, typename CoordinateSystem, std::size_t Dimension>
+struct access<model::d2::point_xy<CoordinateType, CoordinateSystem>, Dimension >
+{
+ static inline CoordinateType get(
+ model::d2::point_xy<CoordinateType, CoordinateSystem> const& p)
+ {
+ return p.template get<Dimension>();
+ }
+
+ static inline void set(model::d2::point_xy<CoordinateType, CoordinateSystem>& p,
+ CoordinateType const& value)
+ {
+ p.template set<Dimension>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_POINT_XY_HPP
diff --git a/src/boost/geometry/geometries/polygon.hpp b/src/boost/geometry/geometries/polygon.hpp
new file mode 100644
index 0000000..ec8d1ec
--- /dev/null
+++ b/src/boost/geometry/geometries/polygon.hpp
@@ -0,0 +1,319 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/geometries/ring.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+/*!
+\brief The polygon contains an outer ring and zero or more inner rings.
+\ingroup geometries
+\tparam Point point type
+\tparam ClockWise true for clockwise direction,
+ false for CounterClockWise direction
+\tparam Closed true for closed polygons (last point == first point),
+ false open points
+\tparam PointList container type for points,
+ for example std::vector, std::list, std::deque
+\tparam RingList container type for inner rings,
+ for example std::vector, std::list, std::deque
+\tparam PointAlloc container-allocator-type, for the points
+\tparam RingAlloc container-allocator-type, for the rings
+\note The container collecting the points in the rings can be different
+ from the container collecting the inner rings. They all default to vector.
+
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_polygon Polygon Concept]
+}
+
+
+*/
+template
+<
+ typename Point,
+ bool ClockWise = true,
+ bool Closed = true,
+ template<typename, typename> class PointList = std::vector,
+ template<typename, typename> class RingList = std::vector,
+ template<typename> class PointAlloc = std::allocator,
+ template<typename> class RingAlloc = std::allocator
+>
+class polygon
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+public:
+
+ // Member types
+ typedef Point point_type;
+ typedef ring<Point, ClockWise, Closed, PointList, PointAlloc> ring_type;
+ typedef RingList<ring_type , RingAlloc<ring_type > > inner_container_type;
+
+ inline ring_type const& outer() const { return m_outer; }
+ inline inner_container_type const& inners() const { return m_inners; }
+
+ inline ring_type& outer() { return m_outer; }
+ inline inner_container_type & inners() { return m_inners; }
+
+ /// Utility method, clears outer and inner rings
+ inline void clear()
+ {
+ m_outer.clear();
+ m_inners.clear();
+ }
+
+private:
+
+ ring_type m_outer;
+ inner_container_type m_inners;
+};
+
+
+} // namespace model
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+ typename Point,
+ bool ClockWise, bool Closed,
+ template<typename, typename> class PointList,
+ template<typename, typename> class RingList,
+ template<typename> class PointAlloc,
+ template<typename> class RingAlloc
+>
+struct tag
+<
+ model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList, PointAlloc, RingAlloc
+ >
+>
+{
+ typedef polygon_tag type;
+};
+
+template
+<
+ typename Point,
+ bool ClockWise, bool Closed,
+ template<typename, typename> class PointList,
+ template<typename, typename> class RingList,
+ template<typename> class PointAlloc,
+ template<typename> class RingAlloc
+>
+struct ring_const_type
+<
+ model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList, PointAlloc, RingAlloc
+ >
+>
+{
+ typedef typename model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList,
+ PointAlloc, RingAlloc
+ >::ring_type const& type;
+};
+
+
+template
+<
+ typename Point,
+ bool ClockWise, bool Closed,
+ template<typename, typename> class PointList,
+ template<typename, typename> class RingList,
+ template<typename> class PointAlloc,
+ template<typename> class RingAlloc
+>
+struct ring_mutable_type
+<
+ model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList, PointAlloc, RingAlloc
+ >
+>
+{
+ typedef typename model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList,
+ PointAlloc, RingAlloc
+ >::ring_type& type;
+};
+
+template
+<
+ typename Point,
+ bool ClockWise, bool Closed,
+ template<typename, typename> class PointList,
+ template<typename, typename> class RingList,
+ template<typename> class PointAlloc,
+ template<typename> class RingAlloc
+>
+struct interior_const_type
+<
+ model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList,
+ PointAlloc, RingAlloc
+ >
+>
+{
+ typedef typename model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList,
+ PointAlloc, RingAlloc
+ >::inner_container_type const& type;
+};
+
+
+template
+<
+ typename Point,
+ bool ClockWise, bool Closed,
+ template<typename, typename> class PointList,
+ template<typename, typename> class RingList,
+ template<typename> class PointAlloc,
+ template<typename> class RingAlloc
+>
+struct interior_mutable_type
+<
+ model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList,
+ PointAlloc, RingAlloc
+ >
+>
+{
+ typedef typename model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList,
+ PointAlloc, RingAlloc
+ >::inner_container_type& type;
+};
+
+
+template
+<
+ typename Point,
+ bool ClockWise, bool Closed,
+ template<typename, typename> class PointList,
+ template<typename, typename> class RingList,
+ template<typename> class PointAlloc,
+ template<typename> class RingAlloc
+>
+struct exterior_ring
+<
+ model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList, PointAlloc, RingAlloc
+ >
+>
+{
+ typedef model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList,
+ PointAlloc, RingAlloc
+ > polygon_type;
+
+ static inline typename polygon_type::ring_type& get(polygon_type& p)
+ {
+ return p.outer();
+ }
+
+ static inline typename polygon_type::ring_type const& get(
+ polygon_type const& p)
+ {
+ return p.outer();
+ }
+};
+
+template
+<
+ typename Point,
+ bool ClockWise, bool Closed,
+ template<typename, typename> class PointList,
+ template<typename, typename> class RingList,
+ template<typename> class PointAlloc,
+ template<typename> class RingAlloc
+>
+struct interior_rings
+<
+ model::polygon
+ <
+ Point, ClockWise, Closed,
+ PointList, RingList,
+ PointAlloc, RingAlloc
+ >
+>
+{
+ typedef model::polygon
+ <
+ Point, ClockWise, Closed, PointList, RingList,
+ PointAlloc, RingAlloc
+ > polygon_type;
+
+ static inline typename polygon_type::inner_container_type& get(
+ polygon_type& p)
+ {
+ return p.inners();
+ }
+
+ static inline typename polygon_type::inner_container_type const& get(
+ polygon_type const& p)
+ {
+ return p.inners();
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_POLYGON_HPP
diff --git a/src/boost/geometry/geometries/register/box.hpp b/src/boost/geometry/geometries/register/box.hpp
new file mode 100644
index 0000000..838c2bb
--- /dev/null
+++ b/src/boost/geometry/geometries/register/box.hpp
@@ -0,0 +1,179 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_REGISTER_BOX_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_REGISTER_BOX_HPP
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS(Box, Point, MinCorner, MaxCorner) \
+template <size_t D> \
+struct indexed_access<Box, min_corner, D> \
+{ \
+ typedef typename coordinate_type<Point>::type ct; \
+ static inline ct get(Box const& b) \
+ { return geometry::get<D>(b. MinCorner); } \
+ static inline void set(Box& b, ct const& value) \
+ { geometry::set<D>(b. MinCorner, value); } \
+}; \
+template <size_t D> \
+struct indexed_access<Box, max_corner, D> \
+{ \
+ typedef typename coordinate_type<Point>::type ct; \
+ static inline ct get(Box const& b) \
+ { return geometry::get<D>(b. MaxCorner); } \
+ static inline void set(Box& b, ct const& value) \
+ { geometry::set<D>(b. MaxCorner, value); } \
+};
+
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_TEMPLATED(Box, MinCorner, MaxCorner) \
+template <typename P, size_t D> \
+struct indexed_access<Box<P>, min_corner, D> \
+{ \
+ typedef typename coordinate_type<P>::type ct; \
+ static inline ct get(Box<P> const& b) \
+ { return geometry::get<D>(b. MinCorner); } \
+ static inline void set(Box<P>& b, ct const& value) \
+ { geometry::set<D>(b. MinCorner, value); } \
+}; \
+template <typename P, size_t D> \
+struct indexed_access<Box<P>, max_corner, D> \
+{ \
+ typedef typename coordinate_type<P>::type ct; \
+ static inline ct get(Box<P> const& b) \
+ { return geometry::get<D>(b. MaxCorner); } \
+ static inline void set(Box<P>& b, ct const& value) \
+ { geometry::set<D>(b. MaxCorner, value); } \
+};
+
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_4VALUES(Box, Point, Left, Bottom, Right, Top) \
+template <> struct indexed_access<Box, min_corner, 0> \
+{ \
+ typedef coordinate_type<Point>::type ct; \
+ static inline ct get(Box const& b) { return b. Left; } \
+ static inline void set(Box& b, ct const& value) { b. Left = value; } \
+}; \
+template <> struct indexed_access<Box, min_corner, 1> \
+{ \
+ typedef coordinate_type<Point>::type ct; \
+ static inline ct get(Box const& b) { return b. Bottom; } \
+ static inline void set(Box& b, ct const& value) { b. Bottom = value; } \
+}; \
+template <> struct indexed_access<Box, max_corner, 0> \
+{ \
+ typedef coordinate_type<Point>::type ct; \
+ static inline ct get(Box const& b) { return b. Right; } \
+ static inline void set(Box& b, ct const& value) { b. Right = value; } \
+}; \
+template <> struct indexed_access<Box, max_corner, 1> \
+{ \
+ typedef coordinate_type<Point>::type ct; \
+ static inline ct get(Box const& b) { return b. Top; } \
+ static inline void set(Box& b, ct const& value) { b. Top = value; } \
+};
+
+
+
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, PointType) \
+ template<> struct tag<Box > { typedef box_tag type; }; \
+ template<> struct point_type<Box > { typedef PointType type; };
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS_TEMPLATED(Box) \
+ template<typename P> struct tag<Box<P> > { typedef box_tag type; }; \
+ template<typename P> struct point_type<Box<P> > { typedef P type; };
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+
+/*!
+\brief \brief_macro{box}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_BOX, box} The
+ box may contain template parameters, which must be specified then.
+\param Box \param_macro_type{Box}
+\param Point Point type on which box is based. Might be two or three-dimensional
+\param MinCorner minimum corner (should be public member or method)
+\param MaxCorner maximum corner (should be public member or method)
+
+\qbk{
+[heading Example]
+[register_box]
+[register_box_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_BOX(Box, Point, MinCorner, MaxCorner) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, Point) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS(Box, Point, MinCorner, MaxCorner) \
+}}}
+
+
+/*!
+\brief \brief_macro{box}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_BOX_TEMPLATED, box}
+ \details_macro_templated{box, point}
+\param Box \param_macro_type{Box}
+\param MinCorner minimum corner (should be public member or method)
+\param MaxCorner maximum corner (should be public member or method)
+
+\qbk{
+[heading Example]
+[register_box_templated]
+[register_box_templated_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_BOX_TEMPLATED(Box, MinCorner, MaxCorner) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS_TEMPLATED(Box) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_TEMPLATED(Box, MinCorner, MaxCorner) \
+}}}
+
+/*!
+\brief \brief_macro{box}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_BOX_2D_4VALUES, box}
+\param Box \param_macro_type{Box}
+\param Point Point type reported as point_type by box. Must be two dimensional.
+ Note that these box tyeps do not contain points, but they must have a
+ related point_type
+\param Left Left side (must be public member or method)
+\param Bottom Bottom side (must be public member or method)
+\param Right Right side (must be public member or method)
+\param Top Top side (must be public member or method)
+
+\qbk{
+[heading Example]
+[register_box_2d_4values]
+[register_box_2d_4values_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_BOX_2D_4VALUES(Box, Point, Left, Bottom, Right, Top) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, Point) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_4VALUES(Box, Point, Left, Bottom, Right, Top) \
+}}}
+
+
+
+// CONST versions are for boxes probably not that common. Postponed.
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_REGISTER_BOX_HPP
diff --git a/src/boost/geometry/geometries/register/linestring.hpp b/src/boost/geometry/geometries/register/linestring.hpp
new file mode 100644
index 0000000..b064398
--- /dev/null
+++ b/src/boost/geometry/geometries/register/linestring.hpp
@@ -0,0 +1,60 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_REGISTER_LINESTRING_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_REGISTER_LINESTRING_HPP
+
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+/*!
+\brief \brief_macro{linestring}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_LINESTRING, linestring} The
+ linestring may contain template parameters, which must be specified then.
+\param Linestring \param_macro_type{linestring}
+
+\qbk{
+[heading Example]
+[register_linestring]
+[register_linestring_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_LINESTRING(Linestring) \
+namespace boost { namespace geometry { namespace traits { \
+ template<> struct tag<Linestring> { typedef linestring_tag type; }; \
+}}}
+
+
+/*!
+\brief \brief_macro{templated linestring}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED, templated linestring}
+ \details_macro_templated{linestring, point}
+\param Linestring \param_macro_type{linestring (without template parameters)}
+
+\qbk{
+[heading Example]
+[register_linestring_templated]
+[register_linestring_templated_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(Linestring) \
+namespace boost { namespace geometry { namespace traits { \
+ template<typename P> struct tag< Linestring<P> > { typedef linestring_tag type; }; \
+}}}
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_REGISTER_LINESTRING_HPP
diff --git a/src/boost/geometry/geometries/register/point.hpp b/src/boost/geometry/geometries/register/point.hpp
new file mode 100644
index 0000000..6765825
--- /dev/null
+++ b/src/boost/geometry/geometries/register/point.hpp
@@ -0,0 +1,173 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_REGISTER_POINT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_REGISTER_POINT_HPP
+
+
+#include <cstddef>
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+// Starting point, specialize basic traits necessary to register a point
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, Dim, CoordinateType, CoordinateSystem) \
+ template<> struct tag<Point> { typedef point_tag type; }; \
+ template<> struct dimension<Point> : boost::mpl::int_<Dim> {}; \
+ template<> struct coordinate_type<Point> { typedef CoordinateType type; }; \
+ template<> struct coordinate_system<Point> { typedef CoordinateSystem type; };
+
+// Specialize access class per dimension
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, Dim, CoordinateType, Get, Set) \
+ template<> struct access<Point, Dim> \
+ { \
+ static inline CoordinateType get(Point const& p) { return p. Get; } \
+ static inline void set(Point& p, CoordinateType const& value) { p. Set = value; } \
+ };
+
+// Const version
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, Dim, CoordinateType, Get) \
+ template<> struct access<Point, Dim> \
+ { \
+ static inline CoordinateType get(Point const& p) { return p. Get; } \
+ };
+
+
+// Getter/setter version
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_GET_SET(Point, Dim, CoordinateType, Get, Set) \
+ template<> struct access<Point, Dim> \
+ { \
+ static inline CoordinateType get(Point const& p) \
+ { return p. Get (); } \
+ static inline void set(Point& p, CoordinateType const& value) \
+ { p. Set ( value ); } \
+ };
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+/*!
+\brief \brief_macro{2D point type}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_POINT_2D, two-dimensional point type}
+\param Point \param_macro_type{Point}
+\param CoordinateType \param_macro_coortype{point}
+\param CoordinateSystem \param_macro_coorsystem
+\param Field0 \param_macro_member{\macro_x}
+\param Field1 \param_macro_member{\macro_y}
+
+\qbk{[include reference/geometries/register/point.qbk]}
+*/
+#define BOOST_GEOMETRY_REGISTER_POINT_2D(Point, CoordinateType, CoordinateSystem, Field0, Field1) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, 0, CoordinateType, Field0, Field0) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, 1, CoordinateType, Field1, Field1) \
+}}}
+
+/*!
+\brief \brief_macro{3D point type}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_POINT_3D, three-dimensional point type}
+\param Point \param_macro_type{Point}
+\param CoordinateType \param_macro_coortype{point}
+\param CoordinateSystem \param_macro_coorsystem
+\param Field0 \param_macro_member{\macro_x}
+\param Field1 \param_macro_member{\macro_y}
+\param Field2 \param_macro_member{\macro_z}
+*/
+#define BOOST_GEOMETRY_REGISTER_POINT_3D(Point, CoordinateType, CoordinateSystem, Field0, Field1, Field2) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, 0, CoordinateType, Field0, Field0) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, 1, CoordinateType, Field1, Field1) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, 2, CoordinateType, Field2, Field2) \
+}}}
+
+/*!
+\brief \brief_macro{2D point type} \brief_macro_const
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_POINT_2D_CONST, two-dimensional point type}. \details_macro_const
+\param Point \param_macro_type{Point}
+\param CoordinateType \param_macro_coortype{point}
+\param CoordinateSystem \param_macro_coorsystem
+\param Field0 \param_macro_member{\macro_x}
+\param Field1 \param_macro_member{\macro_y}
+*/
+#define BOOST_GEOMETRY_REGISTER_POINT_2D_CONST(Point, CoordinateType, CoordinateSystem, Field0, Field1) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, 0, CoordinateType, Field0) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, 1, CoordinateType, Field1) \
+}}}
+
+/*!
+\brief \brief_macro{3D point type} \brief_macro_const
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_POINT_3D_CONST, three-dimensional point type}. \details_macro_const
+\param Point \param_macro_type{Point}
+\param CoordinateType \param_macro_coortype{point}
+\param CoordinateSystem \param_macro_coorsystem
+\param Field0 \param_macro_member{\macro_x}
+\param Field1 \param_macro_member{\macro_y}
+\param Field2 \param_macro_member{\macro_z}
+*/
+#define BOOST_GEOMETRY_REGISTER_POINT_3D_CONST(Point, CoordinateType, CoordinateSystem, Field0, Field1, Field2) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, 0, CoordinateType, Field0) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, 1, CoordinateType, Field1) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, 2, CoordinateType, Field2) \
+}}}
+
+/*!
+\brief \brief_macro{2D point type} \brief_macro_getset
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET, two-dimensional point type}. \details_macro_getset
+\param Point \param_macro_type{Point}
+\param CoordinateType \param_macro_coortype{point}
+\param CoordinateSystem \param_macro_coorsystem
+\param Get0 \param_macro_getset{get, \macro_x}
+\param Get1 \param_macro_getset{get, \macro_y}
+\param Set0 \param_macro_getset{set, \macro_x}
+\param Set1 \param_macro_getset{set, \macro_y}
+*/
+#define BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(Point, CoordinateType, CoordinateSystem, Get0, Get1, Set0, Set1) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_GET_SET(Point, 0, CoordinateType, Get0, Set0) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_GET_SET(Point, 1, CoordinateType, Get1, Set1) \
+}}}
+
+/*!
+\brief \brief_macro{3D point type} \brief_macro_getset
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_POINT_3D_GET_SET, three-dimensional point type}. \details_macro_getset
+\param Point \param_macro_type{Point}
+\param CoordinateType \param_macro_coortype{point}
+\param CoordinateSystem \param_macro_coorsystem
+\param Get0 \param_macro_getset{get, \macro_x}
+\param Get1 \param_macro_getset{get, \macro_y}
+\param Get2 \param_macro_getset{get, \macro_z}
+\param Set0 \param_macro_getset{set, \macro_x}
+\param Set1 \param_macro_getset{set, \macro_y}
+\param Set2 \param_macro_getset{set, \macro_z}
+*/
+#define BOOST_GEOMETRY_REGISTER_POINT_3D_GET_SET(Point, CoordinateType, CoordinateSystem, Get0, Get1, Get2, Set0, Set1, Set2) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_GET_SET(Point, 0, CoordinateType, Get0, Set0) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_GET_SET(Point, 1, CoordinateType, Get1, Set1) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_GET_SET(Point, 2, CoordinateType, Get2, Set2) \
+}}}
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_REGISTER_POINT_HPP
diff --git a/src/boost/geometry/geometries/register/ring.hpp b/src/boost/geometry/geometries/register/ring.hpp
new file mode 100644
index 0000000..fb6cb67
--- /dev/null
+++ b/src/boost/geometry/geometries/register/ring.hpp
@@ -0,0 +1,60 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_REGISTER_RING_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_REGISTER_RING_HPP
+
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+/*!
+\brief \brief_macro{ring}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_RING, ring} The
+ ring may contain template parameters, which must be specified then.
+\param Ring \param_macro_type{ring}
+
+\qbk{
+[heading Example]
+[register_ring]
+[register_ring_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_RING(Ring) \
+namespace boost { namespace geometry { namespace traits { \
+ template<> struct tag<Ring> { typedef ring_tag type; }; \
+}}}
+
+
+/*!
+\brief \brief_macro{templated ring}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_RING_TEMPLATED, templated ring}
+ \details_macro_templated{ring, point}
+\param Ring \param_macro_type{ring (without template parameters)}
+
+\qbk{
+[heading Example]
+[register_ring_templated]
+[register_ring_templated_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_RING_TEMPLATED(Ring) \
+namespace boost { namespace geometry { namespace traits { \
+ template<typename P> struct tag< Ring<P> > { typedef ring_tag type; }; \
+}}}
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_REGISTER_RING_HPP
diff --git a/src/boost/geometry/geometries/register/segment.hpp b/src/boost/geometry/geometries/register/segment.hpp
new file mode 100644
index 0000000..6ea88c0
--- /dev/null
+++ b/src/boost/geometry/geometries/register/segment.hpp
@@ -0,0 +1,129 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_REGISTER_SEGMENT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_REGISTER_SEGMENT_HPP
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS(Segment, Point, Index0, Index1) \
+template <size_t D> \
+struct indexed_access<Segment, min_corner, D> \
+{ \
+ typedef typename coordinate_type<Point>::type ct; \
+ static inline ct get(Segment const& b) \
+ { return geometry::get<D>(b. Index0); } \
+ static inline void set(Segment& b, ct const& value) \
+ { geometry::set<D>(b. Index0, value); } \
+}; \
+template <size_t D> \
+struct indexed_access<Segment, max_corner, D> \
+{ \
+ typedef typename coordinate_type<Point>::type ct; \
+ static inline ct get(Segment const& b) \
+ { return geometry::get<D>(b. Index1); } \
+ static inline void set(Segment& b, ct const& value) \
+ { geometry::set<D>(b. Index1, value); } \
+};
+
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS_TEMPLATIZED(Segment, Index0, Index1) \
+template <typename P, size_t D> \
+struct indexed_access<Segment<P>, min_corner, D> \
+{ \
+ typedef typename coordinate_type<P>::type ct; \
+ static inline ct get(Segment<P> const& b) \
+ { return geometry::get<D>(b. Index0); } \
+ static inline void set(Segment<P>& b, ct const& value) \
+ { geometry::set<D>(b. Index0, value); } \
+}; \
+template <typename P, size_t D> \
+struct indexed_access<Segment<P>, max_corner, D> \
+{ \
+ typedef typename coordinate_type<P>::type ct; \
+ static inline ct get(Segment<P> const& b) \
+ { return geometry::get<D>(b. Index1); } \
+ static inline void set(Segment<P>& b, ct const& value) \
+ { geometry::set<D>(b. Index1, value); } \
+};
+
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS_4VALUES(Segment, Point, Left, Bottom, Right, Top) \
+template <> struct indexed_access<Segment, min_corner, 0> \
+{ \
+ typedef coordinate_type<Point>::type ct; \
+ static inline ct get(Segment const& b) { return b. Left; } \
+ static inline void set(Segment& b, ct const& value) { b. Left = value; } \
+}; \
+template <> struct indexed_access<Segment, min_corner, 1> \
+{ \
+ typedef coordinate_type<Point>::type ct; \
+ static inline ct get(Segment const& b) { return b. Bottom; } \
+ static inline void set(Segment& b, ct const& value) { b. Bottom = value; } \
+}; \
+template <> struct indexed_access<Segment, max_corner, 0> \
+{ \
+ typedef coordinate_type<Point>::type ct; \
+ static inline ct get(Segment const& b) { return b. Right; } \
+ static inline void set(Segment& b, ct const& value) { b. Right = value; } \
+}; \
+template <> struct indexed_access<Segment, max_corner, 1> \
+{ \
+ typedef coordinate_type<Point>::type ct; \
+ static inline ct get(Segment const& b) { return b. Top; } \
+ static inline void set(Segment& b, ct const& value) { b. Top = value; } \
+};
+
+
+
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS(Segment, PointType) \
+ template<> struct tag<Segment > { typedef segment_tag type; }; \
+ template<> struct point_type<Segment > { typedef PointType type; };
+
+#define BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS_TEMPLATIZED(Segment) \
+ template<typename P> struct tag<Segment<P> > { typedef segment_tag type; }; \
+ template<typename P> struct point_type<Segment<P> > { typedef P type; };
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+
+#define BOOST_GEOMETRY_REGISTER_SEGMENT(Segment, PointType, Index0, Index1) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS(Segment, PointType) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS(Segment, PointType, Index0, Index1) \
+}}}
+
+
+#define BOOST_GEOMETRY_REGISTER_SEGMENT_TEMPLATIZED(Segment, Index0, Index1) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS_TEMPLATIZED(Segment) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS_TEMPLATIZED(Segment, Index0, Index1) \
+}}}
+
+#define BOOST_GEOMETRY_REGISTER_SEGMENT_2D_4VALUES(Segment, PointType, Left, Bottom, Right, Top) \
+namespace boost { namespace geometry { namespace traits { \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS(Segment, PointType) \
+ BOOST_GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS_4VALUES(Segment, PointType, Left, Bottom, Right, Top) \
+}}}
+
+
+
+// CONST versions are for segments probably not that common. Postponed.
+
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_REGISTER_SEGMENT_HPP
diff --git a/src/boost/geometry/geometries/ring.hpp b/src/boost/geometry/geometries/ring.hpp
new file mode 100644
index 0000000..9986197
--- /dev/null
+++ b/src/boost/geometry/geometries/ring.hpp
@@ -0,0 +1,153 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_RING_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_RING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+/*!
+\brief A ring (aka linear ring) is a closed line which should not be selfintersecting
+\ingroup geometries
+\tparam Point point type
+\tparam ClockWise true for clockwise direction,
+ false for CounterClockWise direction
+\tparam Closed true for closed polygons (last point == first point),
+ false open points
+\tparam Container container type, for example std::vector, std::deque
+\tparam Allocator container-allocator-type
+
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_ring Ring Concept]
+}
+*/
+template
+<
+ typename Point,
+ bool ClockWise = true, bool Closed = true,
+ template<typename, typename> class Container = std::vector,
+ template<typename> class Allocator = std::allocator
+>
+class ring : public Container<Point, Allocator<Point> >
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ typedef Container<Point, Allocator<Point> > base_type;
+
+public :
+ /// \constructor_default{ring}
+ inline ring()
+ : base_type()
+ {}
+
+ /// \constructor_begin_end{ring}
+ template <typename Iterator>
+ inline ring(Iterator begin, Iterator end)
+ : base_type(begin, end)
+ {}
+};
+
+} // namespace model
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+ typename Point,
+ bool ClockWise, bool Closed,
+ template<typename, typename> class Container,
+ template<typename> class Allocator
+>
+struct tag<model::ring<Point, ClockWise, Closed, Container, Allocator> >
+{
+ typedef ring_tag type;
+};
+
+
+template
+<
+ typename Point,
+ bool Closed,
+ template<typename, typename> class Container,
+ template<typename> class Allocator
+>
+struct point_order<model::ring<Point, false, Closed, Container, Allocator> >
+{
+ static const order_selector value = counterclockwise;
+};
+
+
+template
+<
+ typename Point,
+ bool Closed,
+ template<typename, typename> class Container,
+ template<typename> class Allocator
+>
+struct point_order<model::ring<Point, true, Closed, Container, Allocator> >
+{
+ static const order_selector value = clockwise;
+};
+
+template
+<
+ typename Point,
+ bool PointOrder,
+ template<typename, typename> class Container,
+ template<typename> class Allocator
+>
+struct closure<model::ring<Point, PointOrder, true, Container, Allocator> >
+{
+ static const closure_selector value = closed;
+};
+
+template
+<
+ typename Point,
+ bool PointOrder,
+ template<typename, typename> class Container,
+ template<typename> class Allocator
+>
+struct closure<model::ring<Point, PointOrder, false, Container, Allocator> >
+{
+ static const closure_selector value = open;
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_RING_HPP
diff --git a/src/boost/geometry/geometries/segment.hpp b/src/boost/geometry/geometries/segment.hpp
new file mode 100644
index 0000000..3f47f79
--- /dev/null
+++ b/src/boost/geometry/geometries/segment.hpp
@@ -0,0 +1,203 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP
+#define BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP
+
+#include <cstddef>
+
+#include <boost/concept/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+/*!
+\brief Class segment: small class containing two points
+\ingroup geometries
+\details From Wikipedia: In geometry, a line segment is a part of a line that is bounded
+ by two distinct end points, and contains every point on the line between its end points.
+\note There is also a point-referring-segment, class referring_segment,
+ containing point references, where points are NOT copied
+*/
+template<typename Point>
+class segment : public std::pair<Point, Point>
+{
+public :
+ inline segment()
+ {}
+
+ inline segment(Point const& p1, Point const& p2)
+ {
+ this->first = p1;
+ this->second = p2;
+ }
+};
+
+
+/*!
+\brief Class segment: small class containing two (templatized) point references
+\ingroup geometries
+\details From Wikipedia: In geometry, a line segment is a part of a line that is bounded
+ by two distinct end points, and contains every point on the line between its end points.
+\note The structure is like std::pair, and can often be used interchangeable.
+Difference is that it refers to points, does not have points.
+\note Like std::pair, points are public available.
+\note type is const or non const, so geometry::segment<P> or geometry::segment<P const>
+\note We cannot derive from std::pair<P&, P&> because of
+reference assignments.
+\tparam ConstOrNonConstPoint point type of the segment, maybe a point or a const point
+*/
+template<typename ConstOrNonConstPoint>
+class referring_segment
+{
+ BOOST_CONCEPT_ASSERT( (
+ typename boost::mpl::if_
+ <
+ boost::is_const<ConstOrNonConstPoint>,
+ concept::Point<ConstOrNonConstPoint>,
+ concept::ConstPoint<ConstOrNonConstPoint>
+ >
+ ) );
+
+ typedef ConstOrNonConstPoint point_type;
+
+public:
+
+ point_type& first;
+ point_type& second;
+
+ inline referring_segment(point_type& p1, point_type& p2)
+ : first(p1)
+ , second(p2)
+ {}
+};
+
+
+} // namespace model
+
+
+// Traits specializations for segment above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename Point>
+struct tag<model::segment<Point> >
+{
+ typedef segment_tag type;
+};
+
+template <typename Point>
+struct point_type<model::segment<Point> >
+{
+ typedef Point type;
+};
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<model::segment<Point>, 0, Dimension>
+{
+ typedef model::segment<Point> segment_type;
+ typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
+
+ static inline coordinate_type get(segment_type const& s)
+ {
+ return geometry::get<Dimension>(s.first);
+ }
+
+ static inline void set(segment_type& s, coordinate_type const& value)
+ {
+ geometry::set<Dimension>(s.first, value);
+ }
+};
+
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<model::segment<Point>, 1, Dimension>
+{
+ typedef model::segment<Point> segment_type;
+ typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
+
+ static inline coordinate_type get(segment_type const& s)
+ {
+ return geometry::get<Dimension>(s.second);
+ }
+
+ static inline void set(segment_type& s, coordinate_type const& value)
+ {
+ geometry::set<Dimension>(s.second, value);
+ }
+};
+
+
+template <typename ConstOrNonConstPoint>
+struct tag<model::referring_segment<ConstOrNonConstPoint> >
+{
+ typedef segment_tag type;
+};
+
+template <typename ConstOrNonConstPoint>
+struct point_type<model::referring_segment<ConstOrNonConstPoint> >
+{
+ typedef ConstOrNonConstPoint type;
+};
+
+template <typename ConstOrNonConstPoint, std::size_t Dimension>
+struct indexed_access<model::referring_segment<ConstOrNonConstPoint>, 0, Dimension>
+{
+ typedef model::referring_segment<ConstOrNonConstPoint> segment_type;
+ typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
+
+ static inline coordinate_type get(segment_type const& s)
+ {
+ return geometry::get<Dimension>(s.first);
+ }
+
+ static inline void set(segment_type& s, coordinate_type const& value)
+ {
+ geometry::set<Dimension>(s.first, value);
+ }
+};
+
+
+template <typename ConstOrNonConstPoint, std::size_t Dimension>
+struct indexed_access<model::referring_segment<ConstOrNonConstPoint>, 1, Dimension>
+{
+ typedef model::referring_segment<ConstOrNonConstPoint> segment_type;
+ typedef typename geometry::coordinate_type<segment_type>::type coordinate_type;
+
+ static inline coordinate_type get(segment_type const& s)
+ {
+ return geometry::get<Dimension>(s.second);
+ }
+
+ static inline void set(segment_type& s, coordinate_type const& value)
+ {
+ geometry::set<Dimension>(s.second, value);
+ }
+};
+
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRIES_SEGMENT_HPP
diff --git a/src/boost/geometry/geometry.hpp b/src/boost/geometry/geometry.hpp
new file mode 100644
index 0000000..b696b65
--- /dev/null
+++ b/src/boost/geometry/geometry.hpp
@@ -0,0 +1,91 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRY_HPP
+#define BOOST_GEOMETRY_GEOMETRY_HPP
+
+// Shortcut to include all header files
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+// Core algorithms
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/topological_dimension.hpp>
+
+
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/arithmetic/dot_product.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <boost/geometry/algorithms/append.hpp>
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/buffer.hpp>
+#include <boost/geometry/algorithms/centroid.hpp>
+#include <boost/geometry/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/algorithms/convex_hull.hpp>
+#include <boost/geometry/algorithms/correct.hpp>
+#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/algorithms/difference.hpp>
+#include <boost/geometry/algorithms/disjoint.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/envelope.hpp>
+#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/algorithms/for_each.hpp>
+#include <boost/geometry/algorithms/intersection.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/length.hpp>
+#include <boost/geometry/algorithms/make.hpp>
+#include <boost/geometry/algorithms/num_geometries.hpp>
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+#include <boost/geometry/algorithms/overlaps.hpp>
+#include <boost/geometry/algorithms/perimeter.hpp>
+#include <boost/geometry/algorithms/reverse.hpp>
+#include <boost/geometry/algorithms/simplify.hpp>
+#include <boost/geometry/algorithms/sym_difference.hpp>
+#include <boost/geometry/algorithms/touches.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+#include <boost/geometry/algorithms/union.hpp>
+#include <boost/geometry/algorithms/unique.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
+// Include multi a.o. because it can give weird effects
+// if you don't (e.g. area=0 of a multipolygon)
+#include <boost/geometry/multi/multi.hpp>
+
+// check includes all concepts
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/for_each_coordinate.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+#include <boost/geometry/io/dsv/write.hpp>
+
+#include <boost/geometry/views/box_view.hpp>
+#include <boost/geometry/views/segment_view.hpp>
+
+#include <boost/geometry/io/io.hpp>
+
+#endif // BOOST_GEOMETRY_GEOMETRY_HPP
diff --git a/src/boost/geometry/io/dsv/write.hpp b/src/boost/geometry/io/dsv/write.hpp
new file mode 100644
index 0000000..62929f8
--- /dev/null
+++ b/src/boost/geometry/io/dsv/write.hpp
@@ -0,0 +1,375 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_DSV_WRITE_HPP
+#define BOOST_GEOMETRY_IO_DSV_WRITE_HPP
+
+#include <cstddef>
+#include <ostream>
+#include <string>
+
+#include <boost/concept_check.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv
+{
+
+struct dsv_settings
+{
+ std::string coordinate_separator;
+ std::string point_open;
+ std::string point_close;
+ std::string point_separator;
+ std::string list_open;
+ std::string list_close;
+ std::string list_separator;
+
+ dsv_settings(std::string const& sep
+ , std::string const& open
+ , std::string const& close
+ , std::string const& psep
+ , std::string const& lopen
+ , std::string const& lclose
+ , std::string const& lsep
+ )
+ : coordinate_separator(sep)
+ , point_open(open)
+ , point_close(close)
+ , point_separator(psep)
+ , list_open(lopen)
+ , list_close(lclose)
+ , list_separator(lsep)
+ {}
+};
+
+/*!
+\brief Stream coordinate of a point as \ref DSV
+*/
+template <typename Point, std::size_t Dimension, std::size_t Count>
+struct stream_coordinate
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Point const& point,
+ dsv_settings const& settings)
+ {
+ os << (Dimension > 0 ? settings.coordinate_separator : "")
+ << get<Dimension>(point);
+
+ stream_coordinate
+ <
+ Point, Dimension + 1, Count
+ >::apply(os, point, settings);
+ }
+};
+
+template <typename Point, std::size_t Count>
+struct stream_coordinate<Point, Count, Count>
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>&,
+ Point const&,
+ dsv_settings const& )
+ {
+ }
+};
+
+/*!
+\brief Stream indexed coordinate of a box/segment as \ref DSV
+*/
+template
+<
+ typename Geometry,
+ std::size_t Index,
+ std::size_t Dimension,
+ std::size_t Count
+>
+struct stream_indexed
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Geometry const& geometry,
+ dsv_settings const& settings)
+ {
+ os << (Dimension > 0 ? settings.coordinate_separator : "")
+ << get<Index, Dimension>(geometry);
+ stream_indexed
+ <
+ Geometry, Index, Dimension + 1, Count
+ >::apply(os, geometry, settings);
+ }
+};
+
+template <typename Geometry, std::size_t Index, std::size_t Count>
+struct stream_indexed<Geometry, Index, Count, Count>
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>&, Geometry const&,
+ dsv_settings const& )
+ {
+ }
+};
+
+/*!
+\brief Stream points as \ref DSV
+*/
+template <typename Point>
+struct dsv_point
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Point const& p,
+ dsv_settings const& settings)
+ {
+ os << settings.point_open;
+ stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p, settings);
+ os << settings.point_close;
+ }
+};
+
+/*!
+\brief Stream ranges as DSV
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename Range>
+struct dsv_range
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Range const& range,
+ dsv_settings const& settings)
+ {
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ bool first = true;
+
+ os << settings.list_open;
+
+ for (iterator_type it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ os << (first ? "" : settings.point_separator)
+ << settings.point_open;
+
+ stream_coordinate
+ <
+ point_type, 0, dimension<point_type>::type::value
+ >::apply(os, *it, settings);
+ os << settings.point_close;
+
+ first = false;
+ }
+
+ os << settings.list_close;
+ }
+
+private:
+ typedef typename boost::range_value<Range>::type point_type;
+};
+
+/*!
+\brief Stream sequence of points as DSV-part, e.g. (1 2),(3 4)
+\note Used in polygon, all multi-geometries
+*/
+
+template <typename Polygon>
+struct dsv_poly
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Polygon const& poly,
+ dsv_settings const& settings)
+ {
+ typedef typename ring_type<Polygon>::type ring;
+
+ os << settings.list_open;
+
+ dsv_range<ring>::apply(os, exterior_ring(poly), settings);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ os << settings.list_separator;
+ dsv_range<ring>::apply(os, *it, settings);
+ }
+ os << settings.list_close;
+ }
+};
+
+template <typename Geometry, std::size_t Index>
+struct dsv_per_index
+{
+ typedef typename point_type<Geometry>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Geometry const& geometry,
+ dsv_settings const& settings)
+ {
+ os << settings.point_open;
+ stream_indexed
+ <
+ Geometry, Index, 0, dimension<Geometry>::type::value
+ >::apply(os, geometry, settings);
+ os << settings.point_close;
+ }
+};
+
+template <typename Geometry>
+struct dsv_indexed
+{
+ typedef typename point_type<Geometry>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Geometry const& geometry,
+ dsv_settings const& settings)
+ {
+ os << settings.list_open;
+ dsv_per_index<Geometry, 0>::apply(os, geometry, settings);
+ os << settings.point_separator;
+ dsv_per_index<Geometry, 1>::apply(os, geometry, settings);
+ os << settings.list_close;
+ }
+};
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct dsv {};
+
+template <typename Point>
+struct dsv<point_tag, Point>
+ : detail::dsv::dsv_point<Point>
+{};
+
+template <typename Linestring>
+struct dsv<linestring_tag, Linestring>
+ : detail::dsv::dsv_range<Linestring>
+{};
+
+template <typename Box>
+struct dsv<box_tag, Box>
+ : detail::dsv::dsv_indexed<Box>
+{};
+
+template <typename Segment>
+struct dsv<segment_tag, Segment>
+ : detail::dsv::dsv_indexed<Segment>
+{};
+
+template <typename Ring>
+struct dsv<ring_tag, Ring>
+ : detail::dsv::dsv_range<Ring>
+{};
+
+template <typename Polygon>
+struct dsv<polygon_tag, Polygon>
+ : detail::dsv::dsv_poly<Polygon>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv
+{
+
+// FIXME: This class is not copyable/assignable but it is used as such --mloskot
+template <typename Geometry>
+class dsv_manipulator
+{
+public:
+
+ inline dsv_manipulator(Geometry const& g,
+ dsv_settings const& settings)
+ : m_geometry(g)
+ , m_settings(settings)
+ {}
+
+ template <typename Char, typename Traits>
+ inline friend std::basic_ostream<Char, Traits>& operator<<(
+ std::basic_ostream<Char, Traits>& os,
+ dsv_manipulator const& m)
+ {
+ dispatch::dsv
+ <
+ typename tag_cast
+ <
+ typename tag<Geometry>::type,
+ multi_tag
+ >::type,
+ Geometry
+ >::apply(os, m.m_geometry, m.m_settings);
+ os.flush();
+ return os;
+ }
+
+private:
+ Geometry const& m_geometry;
+ dsv_settings m_settings;
+};
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+\brief Main DSV-streaming function
+\details DSV stands for Delimiter Separated Values. Geometries can be streamed
+ as DSV. There are defaults for all separators.
+\note Useful for examples and testing purposes
+\note With this function GeoJSON objects can be created, using the right
+ delimiters
+\ingroup utility
+*/
+template <typename Geometry>
+inline detail::dsv::dsv_manipulator<Geometry> dsv(Geometry const& geometry
+ , std::string const& coordinate_separator = ", "
+ , std::string const& point_open = "("
+ , std::string const& point_close = ")"
+ , std::string const& point_separator = ", "
+ , std::string const& list_open = "("
+ , std::string const& list_close = ")"
+ , std::string const& list_separator = ", "
+ )
+{
+ concept::check<Geometry const>();
+
+ return detail::dsv::dsv_manipulator<Geometry>(geometry,
+ detail::dsv::dsv_settings(coordinate_separator,
+ point_open, point_close, point_separator,
+ list_open, list_close, list_separator));
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_DSV_WRITE_HPP
diff --git a/src/boost/geometry/io/io.hpp b/src/boost/geometry/io/io.hpp
new file mode 100644
index 0000000..9340060
--- /dev/null
+++ b/src/boost/geometry/io/io.hpp
@@ -0,0 +1,58 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_HPP
+#define BOOST_GEOMETRY_IO_HPP
+
+#include <boost/geometry/io/wkt/read.hpp>
+#include <boost/geometry/io/wkt/write.hpp>
+
+namespace boost { namespace geometry
+{
+
+struct format_wkt {};
+struct format_wkb {}; // TODO
+struct format_dsv {}; // TODO
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+template <typename Tag, typename Geometry>
+struct read
+{
+};
+
+template <typename Geometry>
+struct read<format_wkt, Geometry>
+{
+ static inline void apply(Geometry& geometry, std::string const& wkt)
+ {
+ read_wkt<typename tag<Geometry>::type, Geometry>::apply(wkt, geometry);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+template <typename Format, typename Geometry>
+inline void read(Geometry& geometry, std::string const& wkt)
+{
+ geometry::concept::check<Geometry>();
+ dispatch::read<Format, Geometry>::apply(geometry, wkt);
+}
+
+// TODO: wriite
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_HPP
diff --git a/src/boost/geometry/io/wkt/detail/prefix.hpp b/src/boost/geometry/io/wkt/detail/prefix.hpp
new file mode 100644
index 0000000..45e43b8
--- /dev/null
+++ b/src/boost/geometry/io/wkt/detail/prefix.hpp
@@ -0,0 +1,45 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKT_DETAIL_PREFIX_HPP
+#define BOOST_GEOMETRY_IO_WKT_DETAIL_PREFIX_HPP
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt
+{
+
+struct prefix_point
+{
+ static inline const char* apply() { return "POINT"; }
+};
+
+struct prefix_polygon
+{
+ static inline const char* apply() { return "POLYGON"; }
+};
+
+struct prefix_linestring
+{
+ static inline const char* apply() { return "LINESTRING"; }
+};
+
+}} // namespace wkt::impl
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_WKT_DETAIL_PREFIX_HPP
diff --git a/src/boost/geometry/io/wkt/detail/wkt_multi.hpp b/src/boost/geometry/io/wkt/detail/wkt_multi.hpp
new file mode 100644
index 0000000..0e5abbc
--- /dev/null
+++ b/src/boost/geometry/io/wkt/detail/wkt_multi.hpp
@@ -0,0 +1,57 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
+#define BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
+
+
+#include <boost/geometry/domains/gis/io/wkt/write.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt
+{
+
+struct prefix_null
+{
+ static inline const char* apply() { return ""; }
+};
+
+struct prefix_multipoint
+{
+ static inline const char* apply() { return "MULTIPOINT"; }
+};
+
+struct prefix_multilinestring
+{
+ static inline const char* apply() { return "MULTILINESTRING"; }
+};
+
+struct prefix_multipolygon
+{
+ static inline const char* apply() { return "MULTIPOLYGON"; }
+};
+
+
+
+}} // namespace wkt::impl
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_DOMAINS_GIS_IO_WKT_DETAIL_WKT_MULTI_HPP
diff --git a/src/boost/geometry/io/wkt/iomanip.hpp b/src/boost/geometry/io/wkt/iomanip.hpp
new file mode 100644
index 0000000..4221a1e
--- /dev/null
+++ b/src/boost/geometry/io/wkt/iomanip.hpp
@@ -0,0 +1,46 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKT_IOMANIP_HPP
+#define BOOST_GEOMETRY_IO_WKT_IOMANIP_HPP
+
+#include <boost/geometry/io/wkt/write.hpp>
+
+// This short file contains only one manipulator, streaming as WKT
+// Don't move contents to as_wkt, developers must be able to choose how to stream
+
+// Don't use namespace boost::geometry, to enable the library to stream custom geometries which
+// are living outside the namespace boost { namespace geometry
+
+//namespace boost { namespace geometry
+//{
+
+
+/*!
+\brief Streams a geometry as Well-Known Text
+\ingroup wkt
+*/
+template<typename Char, typename Traits, typename Geometry>
+inline std::basic_ostream<Char,Traits>& operator<<
+ (
+ std::basic_ostream<Char,Traits> &os,
+ Geometry const& geom
+ )
+{
+ os << boost::geometry::wkt(geom);
+ return os;
+}
+
+//}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_WKT_IOMANIP_HPP
diff --git a/src/boost/geometry/io/wkt/read.hpp b/src/boost/geometry/io/wkt/read.hpp
new file mode 100644
index 0000000..e926939
--- /dev/null
+++ b/src/boost/geometry/io/wkt/read.hpp
@@ -0,0 +1,686 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKT_READ_HPP
+#define BOOST_GEOMETRY_IO_WKT_READ_HPP
+
+#include <string>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/tokenizer.hpp>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range.hpp>
+
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/append.hpp>
+#include <boost/geometry/algorithms/clear.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/exception.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/geometry_id.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/mutable_range.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+#include <boost/geometry/util/coordinate_cast.hpp>
+
+#include <boost/geometry/io/wkt/detail/prefix.hpp>
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Exception showing things wrong with WKT parsing
+\ingroup wkt
+*/
+struct read_wkt_exception : public geometry::exception
+{
+ template <typename Iterator>
+ read_wkt_exception(std::string const& msg,
+ Iterator const& it, Iterator const& end, std::string const& wkt)
+ : message(msg)
+ , wkt(wkt)
+ {
+ if (it != end)
+ {
+ source = " at '";
+ source += it->c_str();
+ source += "'";
+ }
+ complete = message + source + " in '" + wkt.substr(0, 100) + "'";
+ }
+
+ read_wkt_exception(std::string const& msg, std::string const& wkt)
+ : message(msg)
+ , wkt(wkt)
+ {
+ complete = message + "' in (" + wkt.substr(0, 100) + ")";
+ }
+
+ virtual ~read_wkt_exception() throw() {}
+
+ virtual const char* what() const throw()
+ {
+ return complete.c_str();
+ }
+private :
+ std::string source;
+ std::string message;
+ std::string wkt;
+ std::string complete;
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+// (wkt: Well Known Text, defined by OGC for all geometries and implemented by e.g. databases (MySQL, PostGIS))
+namespace detail { namespace wkt
+{
+
+typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+
+template <typename Point, std::size_t Dimension, std::size_t DimensionCount>
+struct parsing_assigner
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ Point& point, std::string const& wkt)
+ {
+ typedef typename coordinate_type<Point>::type coordinate_type;
+
+ // Stop at end of tokens, or at "," ot ")"
+ bool finished = (it == end || *it == "," || *it == ")");
+
+ try
+ {
+ // Initialize missing coordinates to default constructor (zero)
+ // OR
+ // Use lexical_cast for conversion to double/int
+ // Note that it is much slower than atof. However, it is more standard
+ // and in parsing the change in performance falls probably away against
+ // the tokenizing
+ set<Dimension>(point, finished
+ ? coordinate_type()
+ : coordinate_cast<coordinate_type>::apply(*it));
+ }
+ catch(boost::bad_lexical_cast const& blc)
+ {
+ throw read_wkt_exception(blc.what(), it, end, wkt);
+ }
+ catch(std::exception const& e)
+ {
+ throw read_wkt_exception(e.what(), it, end, wkt);
+ }
+ catch(...)
+ {
+ throw read_wkt_exception("", it, end, wkt);
+ }
+
+ parsing_assigner<Point, Dimension + 1, DimensionCount>::apply(
+ (finished ? it : ++it), end, point, wkt);
+ }
+};
+
+template <typename Point, std::size_t DimensionCount>
+struct parsing_assigner<Point, DimensionCount, DimensionCount>
+{
+ static inline void apply(tokenizer::iterator&, tokenizer::iterator, Point&,
+ std::string const&)
+ {
+ }
+};
+
+
+
+template <typename Iterator>
+inline void handle_open_parenthesis(Iterator& it,
+ Iterator const& end, std::string const& wkt)
+{
+ if (it == end || *it != "(")
+ {
+ throw read_wkt_exception("Expected '('", it, end, wkt);
+ }
+ ++it;
+}
+
+
+template <typename Iterator>
+inline void handle_close_parenthesis(Iterator& it,
+ Iterator const& end, std::string const& wkt)
+{
+ if (it != end && *it == ")")
+ {
+ ++it;
+ }
+ else
+ {
+ throw read_wkt_exception("Expected ')'", it, end, wkt);
+ }
+}
+
+template <typename Iterator>
+inline void check_end(Iterator& it,
+ Iterator const& end, std::string const& wkt)
+{
+ if (it != end)
+ {
+ throw read_wkt_exception("Too much tokens", it, end, wkt);
+ }
+}
+
+/*!
+\brief Internal, parses coordinate sequences, strings are formated like "(1 2,3 4,...)"
+\param it token-iterator, should be pre-positioned at "(", is post-positions after last ")"
+\param end end-token-iterator
+\param out Output itererator receiving coordinates
+*/
+template <typename Point>
+struct container_inserter
+{
+ // Version with output iterator
+ template <typename OutputIterator>
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, OutputIterator out)
+ {
+ handle_open_parenthesis(it, end, wkt);
+
+ Point point;
+
+ // Parse points until closing parenthesis
+
+ while (it != end && *it != ")")
+ {
+ parsing_assigner
+ <
+ Point,
+ 0,
+ dimension<Point>::value
+ >::apply(it, end, point, wkt);
+ out = point;
+ ++out;
+ if (it != end && *it == ",")
+ {
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+
+// Geometry is a value-type or reference-type
+template <typename Geometry>
+struct container_appender
+{
+ typedef typename geometry::point_type
+ <
+ typename boost::remove_reference<Geometry>::type
+ >::type point_type;
+
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, Geometry out)
+ {
+ handle_open_parenthesis(it, end, wkt);
+
+ point_type point;
+
+ // Parse points until closing parenthesis
+
+ while (it != end && *it != ")")
+ {
+ parsing_assigner
+ <
+ point_type,
+ 0,
+ dimension<point_type>::value
+ >::apply(it, end, point, wkt);
+
+ geometry::append(out, point);
+ if (it != end && *it == ",")
+ {
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+/*!
+\brief Internal, parses a point from a string like this "(x y)"
+\note used for parsing points and multi-points
+*/
+template <typename P>
+struct point_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, P& point)
+ {
+ handle_open_parenthesis(it, end, wkt);
+ parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+
+template <typename Geometry>
+struct linestring_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, Geometry& geometry)
+ {
+ container_appender<Geometry&>::apply(it, end, wkt, geometry);
+ }
+};
+
+
+template <typename Ring>
+struct ring_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, Ring& ring)
+ {
+ // A ring should look like polygon((x y,x y,x y...))
+ // So handle the extra opening/closing parentheses
+ // and in between parse using the container-inserter
+ handle_open_parenthesis(it, end, wkt);
+ container_appender<Ring&>::apply(it, end, wkt, ring);
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+
+
+
+/*!
+\brief Internal, parses a polygon from a string like this "((x y,x y),(x y,x y))"
+\note used for parsing polygons and multi-polygons
+*/
+template <typename Polygon>
+struct polygon_parser
+{
+ typedef typename ring_return_type<Polygon>::type ring_return_type;
+ typedef container_appender<ring_return_type> appender;
+
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, Polygon& poly)
+ {
+
+ handle_open_parenthesis(it, end, wkt);
+
+ int n = -1;
+
+ // Stop at ")"
+ while (it != end && *it != ")")
+ {
+ // Parse ring
+ if (++n == 0)
+ {
+ appender::apply(it, end, wkt, exterior_ring(poly));
+ }
+ else
+ {
+ typename ring_type<Polygon>::type ring;
+ appender::apply(it, end, wkt, ring);
+ traits::push_back
+ <
+ typename boost::remove_reference
+ <
+ typename traits::interior_mutable_type<Polygon>::type
+ >::type
+ >::apply(interior_rings(poly), ring);
+ }
+
+ if (it != end && *it == ",")
+ {
+ // Skip "," after ring is parsed
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, end, wkt);
+ }
+};
+
+inline bool one_of(tokenizer::iterator const& it, std::string const& value,
+ bool& is_present)
+{
+ if (boost::iequals(*it, value))
+ {
+ is_present = true;
+ return true;
+ }
+ return false;
+}
+
+inline bool one_of(tokenizer::iterator const& it, std::string const& value,
+ bool& present1, bool& present2)
+{
+ if (boost::iequals(*it, value))
+ {
+ present1 = true;
+ present2 = true;
+ return true;
+ }
+ return false;
+}
+
+
+inline void handle_empty_z_m(tokenizer::iterator& it, tokenizer::iterator end,
+ bool& has_empty, bool& has_z, bool& has_m)
+{
+ has_empty = false;
+ has_z = false;
+ has_m = false;
+
+ // WKT can optionally have Z and M (measured) values as in
+ // POINT ZM (1 1 5 60), POINT M (1 1 80), POINT Z (1 1 5)
+ // GGL supports any of them as coordinate values, but is not aware
+ // of any Measured value.
+ while (it != end
+ && (one_of(it, "M", has_m)
+ || one_of(it, "Z", has_z)
+ || one_of(it, "EMPTY", has_empty)
+ || one_of(it, "MZ", has_m, has_z)
+ || one_of(it, "ZM", has_z, has_m)
+ )
+ )
+ {
+ ++it;
+ }
+}
+
+/*!
+\brief Internal, starts parsing
+\param tokens boost tokens, parsed with separator " " and keeping separator "()"
+\param geometry string to compare with first token
+*/
+template <typename Geometry>
+inline bool initialize(tokenizer const& tokens,
+ std::string const& geometry_name, std::string const& wkt,
+ tokenizer::iterator& it)
+{
+ it = tokens.begin();
+ if (it != tokens.end() && boost::iequals(*it++, geometry_name))
+ {
+ bool has_empty, has_z, has_m;
+
+ handle_empty_z_m(it, tokens.end(), has_empty, has_z, has_m);
+
+ if (has_z && dimension<Geometry>::type::value < 3)
+ {
+ throw read_wkt_exception("Z only allowed for 3 or more dimensions", wkt);
+ }
+ if (has_empty)
+ {
+ check_end(it, tokens.end(), wkt);
+ return false;
+ }
+ // M is ignored at all.
+
+ return true;
+ }
+ throw read_wkt_exception(std::string("Should start with '") + geometry_name + "'", wkt);
+}
+
+
+template <typename Geometry, template<typename> class Parser, typename PrefixPolicy>
+struct geometry_parser
+{
+ static inline void apply(std::string const& wkt, Geometry& geometry)
+ {
+ geometry::clear(geometry);
+
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it;
+ if (initialize<Geometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ {
+ Parser<Geometry>::apply(it, tokens.end(), wkt, geometry);
+ check_end(it, tokens.end(), wkt);
+ }
+ }
+};
+
+
+
+
+
+/*!
+\brief Supports box parsing
+\note OGC does not define the box geometry, and WKT does not support boxes.
+ However, to be generic GGL supports reading and writing from and to boxes.
+ Boxes are outputted as a standard POLYGON. GGL can read boxes from
+ a standard POLYGON, from a POLYGON with 2 points of from a BOX
+\tparam Box the box
+*/
+template <typename Box>
+struct box_parser
+{
+ static inline void apply(std::string const& wkt, Box& box)
+ {
+ bool should_close = false;
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it = tokens.begin();
+ tokenizer::iterator end = tokens.end();
+ if (it != end && boost::iequals(*it, "POLYGON"))
+ {
+ ++it;
+ bool has_empty, has_z, has_m;
+ handle_empty_z_m(it, end, has_empty, has_z, has_m);
+ if (has_empty)
+ {
+ assign_zero(box);
+ return;
+ }
+ handle_open_parenthesis(it, end, wkt);
+ should_close = true;
+ }
+ else if (it != end && boost::iequals(*it, "BOX"))
+ {
+ ++it;
+ }
+ else
+ {
+ throw read_wkt_exception("Should start with 'POLYGON' or 'BOX'", wkt);
+ }
+
+ typedef typename point_type<Box>::type point_type;
+ std::vector<point_type> points;
+ container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
+
+ if (should_close)
+ {
+ handle_close_parenthesis(it, end, wkt);
+ }
+ check_end(it, end, wkt);
+
+ int index = 0;
+ int n = boost::size(points);
+ if (n == 2)
+ {
+ index = 1;
+ }
+ else if (n == 4 || n == 5)
+ {
+ // In case of 4 or 5 points, we do not check the other ones, just
+ // take the opposite corner which is always 2
+ index = 2;
+ }
+ else
+ {
+ throw read_wkt_exception("Box should have 2,4 or 5 points", wkt);
+ }
+
+ geometry::detail::assign_point_to_index<min_corner>(points.front(), box);
+ geometry::detail::assign_point_to_index<max_corner>(points[index], box);
+ }
+};
+
+
+/*!
+\brief Supports segment parsing
+\note OGC does not define the segment, and WKT does not support segmentes.
+ However, it is useful to implement it, also for testing purposes
+\tparam Segment the segment
+*/
+template <typename Segment>
+struct segment_parser
+{
+ static inline void apply(std::string const& wkt, Segment& segment)
+ {
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it = tokens.begin();
+ tokenizer::iterator end = tokens.end();
+ if (it != end &&
+ (boost::iequals(*it, "SEGMENT")
+ || boost::iequals(*it, "LINESTRING") ))
+ {
+ ++it;
+ }
+ else
+ {
+ throw read_wkt_exception("Should start with 'LINESTRING' or 'SEGMENT'", wkt);
+ }
+
+ typedef typename point_type<Segment>::type point_type;
+ std::vector<point_type> points;
+ container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
+
+ check_end(it, end, wkt);
+
+ if (boost::size(points) == 2)
+ {
+ geometry::detail::assign_point_to_index<0>(points.front(), segment);
+ geometry::detail::assign_point_to_index<1>(points.back(), segment);
+ }
+ else
+ {
+ throw read_wkt_exception("Segment should have 2 points", wkt);
+ }
+
+ }
+};
+
+
+
+}} // namespace detail::wkt
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct read_wkt {};
+
+
+template <typename Point>
+struct read_wkt<point_tag, Point>
+ : detail::wkt::geometry_parser
+ <
+ Point,
+ detail::wkt::point_parser,
+ detail::wkt::prefix_point
+ >
+{};
+
+
+template <typename L>
+struct read_wkt<linestring_tag, L>
+ : detail::wkt::geometry_parser
+ <
+ L,
+ detail::wkt::linestring_parser,
+ detail::wkt::prefix_linestring
+ >
+{};
+
+template <typename Ring>
+struct read_wkt<ring_tag, Ring>
+ : detail::wkt::geometry_parser
+ <
+ Ring,
+ detail::wkt::ring_parser,
+ detail::wkt::prefix_polygon
+ >
+{};
+
+template <typename Geometry>
+struct read_wkt<polygon_tag, Geometry>
+ : detail::wkt::geometry_parser
+ <
+ Geometry,
+ detail::wkt::polygon_parser,
+ detail::wkt::prefix_polygon
+ >
+{};
+
+
+// Box (Non-OGC)
+template <typename Box>
+struct read_wkt<box_tag, Box>
+ : detail::wkt::box_parser<Box>
+{};
+
+// Segment (Non-OGC)
+template <typename Segment>
+struct read_wkt<segment_tag, Segment>
+ : detail::wkt::segment_parser<Segment>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+\brief Parses OGC Well-Known Text (\ref WKT) into a geometry (any geometry)
+\ingroup wkt
+\param wkt string containing \ref WKT
+\param geometry output geometry
+\par Example:
+\note It is case insensitive and can have the WKT forms "point", "point m", "point z", "point zm", "point mz"
+\note Empty sequences can have forms as "LINESTRING ()" or "POLYGON(())"
+Small example showing how to use read_wkt to build a point
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_point
+\line {
+\until }
+\par Example:
+Small example showing how to use read_wkt to build a linestring
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_linestring
+\line {
+\until }
+\par Example:
+Small example showing how to use read_wkt to build a polygon
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_polygon
+\line {
+\until }
+*/
+template <typename Geometry>
+inline void read_wkt(std::string const& wkt, Geometry& geometry)
+{
+ geometry::concept::check<Geometry>();
+ dispatch::read_wkt<typename tag<Geometry>::type, Geometry>::apply(wkt, geometry);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_WKT_READ_HPP
diff --git a/src/boost/geometry/io/wkt/stream.hpp b/src/boost/geometry/io/wkt/stream.hpp
new file mode 100644
index 0000000..86e49fd
--- /dev/null
+++ b/src/boost/geometry/io/wkt/stream.hpp
@@ -0,0 +1,40 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKT_STREAM_HPP
+#define BOOST_GEOMETRY_IO_WKT_STREAM_HPP
+
+#include <boost/geometry/io/wkt/write.hpp>
+
+// This short file contains only one manipulator, streaming as WKT
+// Don't include this in any standard-included header file.
+
+// Don't use namespace boost::geometry, to enable the library to stream custom
+// geometries which are living outside the namespace boost::geometry
+
+/*!
+\brief Streams a geometry as Well-Known Text
+\ingroup wkt
+*/
+template<typename Char, typename Traits, typename Geometry>
+inline std::basic_ostream<Char, Traits>& operator<<
+ (
+ std::basic_ostream<Char, Traits> &os,
+ Geometry const& geom
+ )
+{
+ os << boost::geometry::wkt(geom);
+ return os;
+}
+
+#endif // BOOST_GEOMETRY_IO_WKT_STREAM_HPP
diff --git a/src/boost/geometry/io/wkt/wkt.hpp b/src/boost/geometry/io/wkt/wkt.hpp
new file mode 100644
index 0000000..28bd1e4
--- /dev/null
+++ b/src/boost/geometry/io/wkt/wkt.hpp
@@ -0,0 +1,25 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKT_WKT_HPP
+#define BOOST_GEOMETRY_IO_WKT_WKT_HPP
+
+#include <boost/geometry/io/wkt/read.hpp>
+#include <boost/geometry/io/wkt/write.hpp>
+
+// BSG 2011-02-03
+// We don't include stream.hpp by default. That tries to stream anything not known
+// by default (such as ttmath) and reports errors.
+// Users can include stream.hpp themselves (if they want to)
+
+#endif // BOOST_GEOMETRY_IO_WKT_WKT_HPP
diff --git a/src/boost/geometry/io/wkt/write.hpp b/src/boost/geometry/io/wkt/write.hpp
new file mode 100644
index 0000000..a3e3173
--- /dev/null
+++ b/src/boost/geometry/io/wkt/write.hpp
@@ -0,0 +1,376 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_IO_WKT_WRITE_HPP
+#define BOOST_GEOMETRY_IO_WKT_WRITE_HPP
+
+#include <ostream>
+#include <string>
+
+#include <boost/array.hpp>
+#include <boost/concept/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/geometries/ring.hpp>
+
+#include <boost/geometry/io/wkt/detail/prefix.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt
+{
+
+template <typename P, int I, int Count>
+struct stream_coordinate
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os, P const& p)
+ {
+ os << (I > 0 ? " " : "") << get<I>(p);
+ stream_coordinate<P, I + 1, Count>::apply(os, p);
+ }
+};
+
+template <typename P, int Count>
+struct stream_coordinate<P, Count, Count>
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>&, P const&)
+ {}
+};
+
+struct prefix_linestring_par
+{
+ static inline const char* apply() { return "LINESTRING("; }
+};
+
+struct prefix_ring_par_par
+{
+ // Note, double parentheses are intentional, indicating WKT ring begin/end
+ static inline const char* apply() { return "POLYGON(("; }
+};
+
+struct opening_parenthesis
+{
+ static inline const char* apply() { return "("; }
+};
+
+struct closing_parenthesis
+{
+ static inline const char* apply() { return ")"; }
+};
+
+struct double_closing_parenthesis
+{
+ static inline const char* apply() { return "))"; }
+};
+
+/*!
+\brief Stream points as \ref WKT
+*/
+template <typename Point, typename Policy>
+struct wkt_point
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os, Point const& p)
+ {
+ os << Policy::apply() << "(";
+ stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p);
+ os << ")";
+ }
+};
+
+/*!
+\brief Stream ranges as WKT
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename Range, typename PrefixPolicy, typename SuffixPolicy>
+struct wkt_range
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Range const& range)
+ {
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ bool first = true;
+
+ os << PrefixPolicy::apply();
+
+ // TODO: check EMPTY here
+
+ for (iterator_type it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ os << (first ? "" : ",");
+ stream_coordinate
+ <
+ point_type, 0, dimension<point_type>::type::value
+ >::apply(os, *it);
+ first = false;
+ }
+
+ os << SuffixPolicy::apply();
+ }
+
+private:
+ typedef typename boost::range_value<Range>::type point_type;
+};
+
+/*!
+\brief Stream sequence of points as WKT-part, e.g. (1 2),(3 4)
+\note Used in polygon, all multi-geometries
+*/
+template <typename Range>
+struct wkt_sequence
+ : wkt_range
+ <
+ Range,
+ opening_parenthesis,
+ closing_parenthesis
+ >
+{};
+
+template <typename Polygon, typename PrefixPolicy>
+struct wkt_poly
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Polygon const& poly)
+ {
+ typedef typename ring_type<Polygon const>::type ring;
+
+ os << PrefixPolicy::apply();
+ // TODO: check EMPTY here
+ os << "(";
+ wkt_sequence<ring>::apply(os, exterior_ring(poly));
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ os << ",";
+ wkt_sequence<ring>::apply(os, *it);
+ }
+ os << ")";
+ }
+};
+
+template <typename Box>
+struct wkt_box
+{
+ typedef typename point_type<Box>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Box const& box)
+ {
+ // Convert to ring, then stream
+ typedef model::ring<point_type> ring_type;
+ ring_type ring;
+ geometry::convert(box, ring);
+ os << "POLYGON(";
+ wkt_sequence<ring_type>::apply(os, ring);
+ os << ")";
+ }
+
+ private:
+
+ inline wkt_box()
+ {
+ // Only streaming of boxes with two dimensions is support, otherwise it is a polyhedron!
+ //assert_dimension<B, 2>();
+ }
+};
+
+
+template <typename Segment>
+struct wkt_segment
+{
+ typedef typename point_type<Segment>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Segment const& segment)
+ {
+ // Convert to two points, then stream
+ typedef boost::array<point_type, 2> sequence;
+
+ sequence points;
+ geometry::detail::assign_point_from_index<0>(segment, points[0]);
+ geometry::detail::assign_point_from_index<1>(segment, points[1]);
+
+ // In Boost.Geometry a segment is represented
+ // in WKT-format like (for 2D): LINESTRING(x y,x y)
+ os << "LINESTRING";
+ wkt_sequence<sequence>::apply(os, points);
+ }
+
+ private:
+
+ inline wkt_segment()
+ {}
+};
+
+}} // namespace detail::wkt
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct wkt
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+template <typename Point>
+struct wkt<point_tag, Point>
+ : detail::wkt::wkt_point
+ <
+ Point,
+ detail::wkt::prefix_point
+ >
+{};
+
+template <typename Linestring>
+struct wkt<linestring_tag, Linestring>
+ : detail::wkt::wkt_range
+ <
+ Linestring,
+ detail::wkt::prefix_linestring_par,
+ detail::wkt::closing_parenthesis
+ >
+{};
+
+/*!
+\brief Specialization to stream a box as WKT
+\details A "box" does not exist in WKT.
+It is therefore streamed as a polygon
+*/
+template <typename Box>
+struct wkt<box_tag, Box>
+ : detail::wkt::wkt_box<Box>
+{};
+
+template <typename Segment>
+struct wkt<segment_tag, Segment>
+ : detail::wkt::wkt_segment<Segment>
+{};
+
+/*!
+\brief Specialization to stream a ring as WKT
+\details A ring or "linear_ring" does not exist in WKT.
+A ring is equivalent to a polygon without inner rings
+It is therefore streamed as a polygon
+*/
+template <typename Ring>
+struct wkt<ring_tag, Ring>
+ : detail::wkt::wkt_range
+ <
+ Ring,
+ detail::wkt::prefix_ring_par_par,
+ detail::wkt::double_closing_parenthesis
+ >
+{};
+
+/*!
+\brief Specialization to stream polygon as WKT
+*/
+template <typename Polygon>
+struct wkt<polygon_tag, Polygon>
+ : detail::wkt::wkt_poly
+ <
+ Polygon,
+ detail::wkt::prefix_polygon
+ >
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup wkt
+\details Stream manipulator, streams geometry classes as \ref WKT streams
+\par Example:
+Small example showing how to use the wkt class
+\dontinclude doxygen_1.cpp
+\skip example_as_wkt_point
+\line {
+\until }
+*/
+template <typename Geometry>
+class wkt_manipulator
+{
+public:
+
+ inline wkt_manipulator(Geometry const& g)
+ : m_geometry(g)
+ {}
+
+ template <typename Char, typename Traits>
+ inline friend std::basic_ostream<Char, Traits>& operator<<(
+ std::basic_ostream<Char, Traits>& os,
+ wkt_manipulator const& m)
+ {
+ dispatch::wkt
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::apply(os, m.m_geometry);
+ os.flush();
+ return os;
+ }
+
+private:
+ Geometry const& m_geometry;
+};
+
+/*!
+\brief Main WKT-streaming function
+\ingroup wkt
+\par Example:
+Small example showing how to use the wkt helper function
+\dontinclude doxygen_1.cpp
+\skip example_as_wkt_vector
+\line {
+\until }
+*/
+template <typename Geometry>
+inline wkt_manipulator<Geometry> wkt(Geometry const& geometry)
+{
+ concept::check<Geometry const>();
+
+ return wkt_manipulator<Geometry>(geometry);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_IO_WKT_WRITE_HPP
diff --git a/src/boost/geometry/iterators/base.hpp b/src/boost/geometry/iterators/base.hpp
new file mode 100644
index 0000000..1e82465
--- /dev/null
+++ b/src/boost/geometry/iterators/base.hpp
@@ -0,0 +1,70 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ITERATORS_BASE_HPP
+#define BOOST_GEOMETRY_ITERATORS_BASE_HPP
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/mpl/if.hpp>
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace boost { namespace geometry { namespace detail { namespace iterators
+{
+
+template
+<
+ typename DerivedClass,
+ typename Iterator,
+ typename TraversalFlag = boost::bidirectional_traversal_tag
+>
+struct iterator_base
+ : public boost::iterator_adaptor
+ <
+ DerivedClass,
+ Iterator,
+ boost::use_default,
+ typename boost::mpl::if_
+ <
+ boost::is_convertible
+ <
+ typename boost::iterator_traversal<Iterator>::type,
+ boost::random_access_traversal_tag
+ >,
+ TraversalFlag,
+ boost::use_default
+ >::type
+ >
+{
+ // Define operator cast to Iterator to be able to write things like Iterator it = myit++
+ inline operator Iterator() const
+ {
+ return this->base();
+ }
+
+ /*inline bool operator==(Iterator const& other) const
+ {
+ return this->base() == other;
+ }
+ inline bool operator!=(Iterator const& other) const
+ {
+ return ! operator==(other);
+ }*/
+};
+
+}}}} // namespace boost::geometry::detail::iterators
+#endif
+
+
+#endif // BOOST_GEOMETRY_ITERATORS_BASE_HPP
diff --git a/src/boost/geometry/iterators/closing_iterator.hpp b/src/boost/geometry/iterators/closing_iterator.hpp
new file mode 100644
index 0000000..7cd8fa0
--- /dev/null
+++ b/src/boost/geometry/iterators/closing_iterator.hpp
@@ -0,0 +1,157 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
+#define BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
+
+#include <boost/range.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Iterator which iterates through a range, but adds first element at end of the range
+\tparam Range range on which this class is based on
+\ingroup iterators
+\note Use with "closing_iterator<Range> or "closing_iterator<Range const>
+ to get non-const / const behaviour
+\note This class is normally used from "closeable_view" if Close==true
+*/
+template <typename Range>
+struct closing_iterator
+ : public boost::iterator_facade
+ <
+ closing_iterator<Range>,
+ typename boost::range_value<Range>::type const,
+ boost::random_access_traversal_tag
+ >
+{
+ /// Constructor including the range it is based on
+ explicit inline closing_iterator(Range& range)
+ : m_range(&range)
+ , m_iterator(boost::begin(range))
+ , m_end(boost::end(range))
+ , m_size(boost::size(range))
+ , m_index(0)
+ {}
+
+ /// Constructor to indicate the end of a range
+ explicit inline closing_iterator(Range& range, bool)
+ : m_range(&range)
+ , m_iterator(boost::end(range))
+ , m_end(boost::end(range))
+ , m_size(boost::size(range))
+ , m_index(m_size + 1)
+ {}
+
+ /// Default constructor
+ explicit inline closing_iterator()
+ : m_range(NULL)
+ , m_size(0)
+ , m_index(0)
+ {}
+
+ inline closing_iterator<Range>& operator=(closing_iterator<Range> const& source)
+ {
+ m_range = source.m_range;
+ m_iterator = source.m_iterator;
+ m_end = source.m_end;
+ m_size = source.m_size;
+ m_index = source.m_index;
+ return *this;
+ }
+
+ typedef std::ptrdiff_t difference_type;
+
+private:
+ friend class boost::iterator_core_access;
+
+ inline typename boost::range_value<Range>::type const& dereference() const
+ {
+ return *m_iterator;
+ }
+
+ inline difference_type distance_to(closing_iterator<Range> const& other) const
+ {
+ return other.m_index - this->m_index;
+ }
+
+ inline bool equal(closing_iterator<Range> const& other) const
+ {
+ return this->m_range == other.m_range
+ && this->m_index == other.m_index;
+ }
+
+ inline void increment()
+ {
+ if (++m_index < m_size)
+ {
+ ++m_iterator;
+ }
+ else
+ {
+ update_iterator();
+ }
+ }
+
+ inline void decrement()
+ {
+ if (m_index-- < m_size)
+ {
+ --m_iterator;
+ }
+ else
+ {
+ update_iterator();
+ }
+ }
+
+ inline void advance(difference_type n)
+ {
+ if (m_index < m_size && m_index + n < m_size)
+ {
+ m_index += n;
+ m_iterator += n;
+ }
+ else
+ {
+ m_index += n;
+ update_iterator();
+ }
+ }
+
+ inline void update_iterator()
+ {
+ this->m_iterator = m_index <= m_size
+ ? boost::begin(*m_range) + (m_index % m_size)
+ : boost::end(*m_range)
+ ;
+ }
+
+ Range* m_range;
+ typename boost::range_iterator<Range>::type m_iterator;
+ typename boost::range_iterator<Range>::type m_end;
+ difference_type m_size;
+ difference_type m_index;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
diff --git a/src/boost/geometry/iterators/ever_circling_iterator.hpp b/src/boost/geometry/iterators/ever_circling_iterator.hpp
new file mode 100644
index 0000000..566669e
--- /dev/null
+++ b/src/boost/geometry/iterators/ever_circling_iterator.hpp
@@ -0,0 +1,212 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
+#define BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
+
+#include <boost/range.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <boost/geometry/iterators/base.hpp>
+
+namespace boost { namespace geometry
+{
+
+/*!
+ \brief Iterator which ever circles through a range
+ \tparam Iterator iterator on which this class is based on
+ \ingroup iterators
+ \details If the iterator arrives at range.end() it restarts from the
+ beginning. So it has to be stopped in another way.
+ Don't call for(....; it++) because it will turn in an endless loop
+ \note Name inspired on David Bowie's
+ "Chant Of The Ever Circling Skeletal Family"
+*/
+template <typename Iterator>
+struct ever_circling_iterator :
+ public detail::iterators::iterator_base
+ <
+ ever_circling_iterator<Iterator>,
+ Iterator
+ >
+{
+ friend class boost::iterator_core_access;
+
+ explicit inline ever_circling_iterator(Iterator begin, Iterator end,
+ bool skip_first = false)
+ : m_begin(begin)
+ , m_end(end)
+ , m_skip_first(skip_first)
+ {
+ this->base_reference() = begin;
+ }
+
+ explicit inline ever_circling_iterator(Iterator begin, Iterator end, Iterator start,
+ bool skip_first = false)
+ : m_begin(begin)
+ , m_end(end)
+ , m_skip_first(skip_first)
+ {
+ this->base_reference() = start;
+ }
+
+ /// Navigate to a certain position, should be in [start .. end], if at end
+ /// it will circle again.
+ inline void moveto(Iterator it)
+ {
+ this->base_reference() = it;
+ check_end();
+ }
+
+private:
+
+ inline void increment(bool possibly_skip = true)
+ {
+ (this->base_reference())++;
+ check_end(possibly_skip);
+ }
+
+ inline void check_end(bool possibly_skip = true)
+ {
+ if (this->base() == this->m_end)
+ {
+ this->base_reference() = this->m_begin;
+ if (m_skip_first && possibly_skip)
+ {
+ increment(false);
+ }
+ }
+ }
+
+ Iterator m_begin;
+ Iterator m_end;
+ bool m_skip_first;
+};
+
+template <typename Range>
+struct ever_circling_range_iterator
+ : public boost::iterator_facade
+ <
+ ever_circling_range_iterator<Range>,
+ typename boost::range_value<Range>::type const,
+ boost::random_access_traversal_tag
+ >
+{
+ /// Constructor including the range it is based on
+ explicit inline ever_circling_range_iterator(Range& range)
+ : m_range(&range)
+ , m_iterator(boost::begin(range))
+ , m_size(boost::size(range))
+ , m_index(0)
+ {}
+
+ /// Default constructor
+ explicit inline ever_circling_range_iterator()
+ : m_range(NULL)
+ , m_size(0)
+ , m_index(0)
+ {}
+
+ inline ever_circling_range_iterator<Range>& operator=(ever_circling_range_iterator<Range> const& source)
+ {
+ m_range = source.m_range;
+ m_iterator = source.m_iterator;
+ m_size = source.m_size;
+ m_index = source.m_index;
+ return *this;
+ }
+
+ typedef std::ptrdiff_t difference_type;
+
+private:
+ friend class boost::iterator_core_access;
+
+ inline typename boost::range_value<Range>::type const& dereference() const
+ {
+ return *m_iterator;
+ }
+
+ inline difference_type distance_to(ever_circling_range_iterator<Range> const& other) const
+ {
+ return other.m_index - this->m_index;
+ }
+
+ inline bool equal(ever_circling_range_iterator<Range> const& other) const
+ {
+ return this->m_range == other.m_range
+ && this->m_index == other.m_index;
+ }
+
+ inline void increment()
+ {
+ ++m_index;
+ if (m_index >= 0 && m_index < m_size)
+ {
+ ++m_iterator;
+ }
+ else
+ {
+ update_iterator();
+ }
+ }
+
+ inline void decrement()
+ {
+ --m_index;
+ if (m_index >= 0 && m_index < m_size)
+ {
+ --m_iterator;
+ }
+ else
+ {
+ update_iterator();
+ }
+ }
+
+ inline void advance(difference_type n)
+ {
+ if (m_index >= 0 && m_index < m_size
+ && m_index + n >= 0 && m_index + n < m_size)
+ {
+ m_index += n;
+ m_iterator += n;
+ }
+ else
+ {
+ m_index += n;
+ update_iterator();
+ }
+ }
+
+ inline void update_iterator()
+ {
+ while (m_index < 0)
+ {
+ m_index += m_size;
+ }
+ m_index = m_index % m_size;
+ this->m_iterator = boost::begin(*m_range) + m_index;
+ }
+
+ Range* m_range;
+ typename boost::range_iterator<Range>::type m_iterator;
+ difference_type m_size;
+ difference_type m_index;
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
diff --git a/src/boost/geometry/multi/algorithms/append.hpp b/src/boost/geometry/multi/algorithms/append.hpp
new file mode 100644
index 0000000..e72be03
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/append.hpp
@@ -0,0 +1,52 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
+
+#include <boost/geometry/algorithms/append.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+namespace splitted_dispatch
+{
+
+template <typename Geometry, typename Point>
+struct append_point<multi_point_tag, Geometry, Point>
+ : detail::append::append_point<Geometry, Point>
+{};
+
+template <typename Geometry, typename Range>
+struct append_range<multi_point_tag, Geometry, Range>
+ : detail::append::append_range<Geometry, Range>
+{};
+
+}
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
diff --git a/src/boost/geometry/multi/algorithms/area.hpp b/src/boost/geometry/multi/algorithms/area.hpp
new file mode 100644
index 0000000..6695686
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/area.hpp
@@ -0,0 +1,57 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+#include <boost/geometry/multi/algorithms/detail/multi_sum.hpp>
+#include <boost/geometry/multi/algorithms/num_points.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+template <typename MultiGeometry, typename Strategy>
+struct area<MultiGeometry, Strategy, multi_polygon_tag>
+ : detail::multi_sum
+ <
+ typename Strategy::return_type,
+ MultiGeometry,
+ Strategy,
+ area
+ <
+ typename boost::range_value<MultiGeometry>::type,
+ Strategy,
+ polygon_tag
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP
diff --git a/src/boost/geometry/multi/algorithms/centroid.hpp b/src/boost/geometry/multi/algorithms/centroid.hpp
new file mode 100644
index 0000000..855ed22
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/centroid.hpp
@@ -0,0 +1,178 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/centroid.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+#include <boost/geometry/multi/algorithms/num_points.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace centroid
+{
+
+
+/*!
+ \brief Building block of a multi-point, to be used as Policy in the
+ more generec centroid_multi
+*/
+template
+<
+ typename Point,
+ typename Strategy
+>
+struct centroid_multi_point_state
+{
+ static inline void apply(Point const& point,
+ Strategy const& strategy, typename Strategy::state_type& state)
+ {
+ strategy.apply(point, state);
+ }
+};
+
+
+
+/*!
+ \brief Generic implementation which calls a policy to calculate the
+ centroid of the total of its single-geometries
+ \details The Policy is, in general, the single-version, with state. So
+ detail::centroid::centroid_polygon_state is used as a policy for this
+ detail::centroid::centroid_multi
+
+*/
+template
+<
+ typename Multi,
+ typename Point,
+ typename Strategy,
+ typename Policy
+>
+struct centroid_multi
+{
+ static inline void apply(Multi const& multi, Point& centroid,
+ Strategy const& strategy)
+ {
+#if ! defined(BOOST_GEOMETRY_CENTROID_NO_THROW)
+ // If there is nothing in any of the ranges, it is not possible
+ // to calculate the centroid
+ if (geometry::num_points(multi) == 0)
+ {
+ throw centroid_exception();
+ }
+#endif
+
+ typename Strategy::state_type state;
+
+ for (typename boost::range_iterator<Multi const>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ Policy::apply(*it, strategy, state);
+ }
+ Strategy::result(state, centroid);
+ }
+};
+
+
+
+}} // namespace detail::centroid
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename MultiLinestring,
+ typename Point,
+ typename Strategy
+>
+struct centroid<multi_linestring_tag, MultiLinestring, Point, Strategy>
+ : detail::centroid::centroid_multi
+ <
+ MultiLinestring,
+ Point,
+ Strategy,
+ detail::centroid::centroid_range_state
+ <
+ typename boost::range_value<MultiLinestring>::type,
+ closed,
+ Strategy
+ >
+ >
+{};
+
+template
+<
+ typename MultiPolygon,
+ typename Point,
+ typename Strategy
+>
+struct centroid<multi_polygon_tag, MultiPolygon, Point, Strategy>
+ : detail::centroid::centroid_multi
+ <
+ MultiPolygon,
+ Point,
+ Strategy,
+ detail::centroid::centroid_polygon_state
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >
+{};
+
+
+template
+<
+ typename MultiPoint,
+ typename Point,
+ typename Strategy
+>
+struct centroid<multi_point_tag, MultiPoint, Point, Strategy>
+ : detail::centroid::centroid_multi
+ <
+ MultiPoint,
+ Point,
+ Strategy,
+ detail::centroid::centroid_multi_point_state
+ <
+ typename boost::range_value<MultiPoint>::type,
+ Strategy
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP
+
diff --git a/src/boost/geometry/multi/algorithms/clear.hpp b/src/boost/geometry/multi/algorithms/clear.hpp
new file mode 100644
index 0000000..0b14b6c
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/clear.hpp
@@ -0,0 +1,43 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP
+
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/algorithms/clear.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry>
+struct clear<Geometry, multi_tag>
+ : detail::clear::collection_clear<Geometry>
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP
diff --git a/src/boost/geometry/multi/algorithms/convert.hpp b/src/boost/geometry/multi/algorithms/convert.hpp
new file mode 100644
index 0000000..4745791
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/convert.hpp
@@ -0,0 +1,128 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace conversion
+{
+
+template <typename Single, typename Multi, typename Policy>
+struct single_to_multi: private Policy
+{
+ static inline void apply(Single const& single, Multi& multi)
+ {
+ traits::resize<Multi>::apply(multi, 1);
+ Policy::apply(single, *boost::begin(multi));
+ }
+};
+
+
+
+template <typename Multi1, typename Multi2, typename Policy>
+struct multi_to_multi: private Policy
+{
+ static inline void apply(Multi1 const& multi1, Multi2& multi2)
+ {
+ traits::resize<Multi2>::apply(multi2, boost::size(multi1));
+
+ typename boost::range_iterator<Multi1 const>::type it1
+ = boost::begin(multi1);
+ typename boost::range_iterator<Multi2>::type it2
+ = boost::begin(multi2);
+
+ for (; it1 != boost::end(multi1); ++it1, ++it2)
+ {
+ Policy::apply(*it1, *it2);
+ }
+ }
+};
+
+
+}} // namespace detail::convert
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// Dispatch for multi <-> multi, specifying their single-version as policy.
+// Note that, even if the multi-types are mutually different, their single
+// version types might be the same and therefore we call boost::is_same again
+
+template <typename Multi1, typename Multi2, std::size_t DimensionCount>
+struct convert<Multi1, Multi2, multi_tag, multi_tag, DimensionCount, false>
+ : detail::conversion::multi_to_multi
+ <
+ Multi1,
+ Multi2,
+ convert
+ <
+ typename boost::range_value<Multi1>::type,
+ typename boost::range_value<Multi2>::type,
+ typename single_tag_of
+ <
+ typename tag<Multi1>::type
+ >::type,
+ typename single_tag_of
+ <
+ typename tag<Multi2>::type
+ >::type,
+ DimensionCount
+ >
+ >
+{};
+
+template <typename Single, typename Multi, typename SingleTag, std::size_t DimensionCount>
+struct convert<Single, Multi, SingleTag, multi_tag, DimensionCount, false>
+ : detail::conversion::single_to_multi
+ <
+ Single,
+ Multi,
+ convert
+ <
+ Single,
+ typename boost::range_value<Multi>::type,
+ typename tag<Single>::type,
+ typename single_tag_of
+ <
+ typename tag<Multi>::type
+ >::type,
+ DimensionCount,
+ false
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP
diff --git a/src/boost/geometry/multi/algorithms/correct.hpp b/src/boost/geometry/multi/algorithms/correct.hpp
new file mode 100644
index 0000000..d0c3e10
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/correct.hpp
@@ -0,0 +1,66 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/algorithms/correct.hpp>
+#include <boost/geometry/multi/algorithms/detail/modify.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiPoint>
+struct correct<MultiPoint, multi_point_tag>
+ : detail::correct::correct_nop<MultiPoint>
+{};
+
+
+template <typename MultiLineString>
+struct correct<MultiLineString, multi_linestring_tag>
+ : detail::correct::correct_nop<MultiLineString>
+{};
+
+
+template <typename Geometry>
+struct correct<Geometry, multi_polygon_tag>
+ : detail::multi_modify
+ <
+ Geometry,
+ detail::correct::correct_polygon
+ <
+ typename boost::range_value<Geometry>::type
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP
diff --git a/src/boost/geometry/multi/algorithms/covered_by.hpp b/src/boost/geometry/multi/algorithms/covered_by.hpp
new file mode 100644
index 0000000..ba398c0
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/covered_by.hpp
@@ -0,0 +1,70 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
+
+
+#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/multi/core/closure.hpp>
+#include <boost/geometry/multi/core/point_order.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/algorithms/within.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Point, typename MultiPolygon>
+struct covered_by<Point, MultiPolygon, point_tag, multi_polygon_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point,
+ MultiPolygon const& multi_polygon, Strategy const& strategy)
+ {
+ return detail::within::geometry_multi_within_code
+ <
+ Point,
+ MultiPolygon,
+ Strategy,
+ detail::within::point_in_polygon
+ <
+ Point,
+ typename boost::range_value<MultiPolygon>::type,
+ order_as_direction
+ <
+ geometry::point_order<MultiPolygon>::value
+ >::value,
+ geometry::closure<MultiPolygon>::value,
+ Strategy
+ >
+ >::apply(point, multi_polygon, strategy) >= 0;
+ }
+};
+
+
+} // namespace dispatch
+
+
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/for_each_range.hpp b/src/boost/geometry/multi/algorithms/detail/for_each_range.hpp
new file mode 100644
index 0000000..08ab14b
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/for_each_range.hpp
@@ -0,0 +1,86 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
+
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/algorithms/detail/for_each_range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each
+{
+
+
+template <typename Multi, typename Actor, bool IsConst>
+struct fe_range_multi
+{
+ static inline void apply(
+ typename add_const_if_c<IsConst, Multi>::type& multi,
+ Actor& actor)
+ {
+ for(BOOST_AUTO_TPL(it, boost::begin(multi)); it != boost::end(multi); ++it)
+ {
+ geometry::detail::for_each_range(*it, actor);
+ }
+ }
+};
+
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPoint, typename Actor, bool IsConst>
+struct for_each_range<multi_point_tag, MultiPoint, Actor, IsConst>
+ : detail::for_each::fe_range_range<MultiPoint, Actor, IsConst>
+{};
+
+template <typename Geometry, typename Actor, bool IsConst>
+struct for_each_range<multi_linestring_tag, Geometry, Actor, IsConst>
+ :
+ detail::for_each::fe_range_multi<Geometry, Actor, IsConst>
+{};
+
+template <typename Geometry, typename Actor, bool IsConst>
+struct for_each_range<multi_polygon_tag, Geometry, Actor, IsConst>
+ :
+ detail::for_each::fe_range_multi<Geometry, Actor, IsConst>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/modify.hpp b/src/boost/geometry/multi/algorithms/detail/modify.hpp
new file mode 100644
index 0000000..b52efd2
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/modify.hpp
@@ -0,0 +1,53 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP
+
+
+#include <boost/range.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename MultiGeometry, typename Policy>
+struct multi_modify
+{
+ static inline void apply(MultiGeometry& multi)
+ {
+ typedef typename boost::range_iterator<MultiGeometry>::type iterator_type;
+ for (iterator_type it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ Policy::apply(*it);
+ }
+ }
+};
+
+
+} // namespace detail
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp b/src/boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp
new file mode 100644
index 0000000..4ae7905
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp
@@ -0,0 +1,52 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
+
+
+#include <boost/range.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename MultiGeometry, typename Predicate, typename Policy>
+struct multi_modify_with_predicate
+{
+ static inline void apply(MultiGeometry& multi, Predicate const& predicate)
+ {
+ typedef typename boost::range_iterator<MultiGeometry>::type iterator_type;
+ for (iterator_type it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ Policy::apply(*it, predicate);
+ }
+ }
+};
+
+
+} // namespace detail
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/multi_sum.hpp b/src/boost/geometry/multi/algorithms/detail/multi_sum.hpp
new file mode 100644
index 0000000..a47685c
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/multi_sum.hpp
@@ -0,0 +1,58 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_SUM_HPP
+#define BOOST_GEOMETRY_MULTI_SUM_HPP
+
+#include <boost/range.hpp>
+
+
+namespace boost { namespace geometry
+{
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template
+<
+ typename ReturnType,
+ typename MultiGeometry,
+ typename Strategy,
+ typename Policy
+>
+struct multi_sum
+{
+ static inline ReturnType apply(MultiGeometry const& geometry, Strategy const& strategy)
+ {
+ ReturnType sum = ReturnType();
+ for (typename boost::range_iterator
+ <
+ MultiGeometry const
+ >::type it = boost::begin(geometry);
+ it != boost::end(geometry);
+ ++it)
+ {
+ sum += Policy::apply(*it, strategy);
+ }
+ return sum;
+ }
+};
+
+
+} // namespace detail
+#endif
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_SUM_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp b/src/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp
new file mode 100644
index 0000000..72be5dd
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp
@@ -0,0 +1,101 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy_segments
+{
+
+
+template
+<
+ typename MultiGeometry,
+ typename SegmentIdentifier,
+ typename PointOut,
+ typename Policy
+>
+struct copy_segment_point_multi
+{
+ static inline bool apply(MultiGeometry const& multi,
+ SegmentIdentifier const& seg_id, bool second,
+ PointOut& point)
+ {
+
+ BOOST_ASSERT
+ (
+ seg_id.multi_index >= 0
+ && seg_id.multi_index < int(boost::size(multi))
+ );
+
+ // Call the single-version
+ return Policy::apply(multi[seg_id.multi_index], seg_id, second, point);
+ }
+};
+
+
+}} // namespace detail::copy_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename MultiGeometry,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename PointOut
+>
+struct copy_segment_point
+ <
+ multi_polygon_tag,
+ MultiGeometry,
+ Reverse,
+ SegmentIdentifier,
+ PointOut
+ >
+ : detail::copy_segments::copy_segment_point_multi
+ <
+ MultiGeometry,
+ SegmentIdentifier,
+ PointOut,
+ detail::copy_segments::copy_segment_point_polygon
+ <
+ typename boost::range_value<MultiGeometry>::type,
+ Reverse,
+ SegmentIdentifier,
+ PointOut
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp b/src/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp
new file mode 100644
index 0000000..f474b12
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp
@@ -0,0 +1,104 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
+
+
+#include <boost/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
+
+#include <boost/geometry/multi/core/ring_type.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy_segments
+{
+
+
+template
+<
+ typename MultiGeometry,
+ typename SegmentIdentifier,
+ typename RangeOut,
+ typename Policy
+>
+struct copy_segments_multi
+{
+ static inline void apply(MultiGeometry const& multi_geometry,
+ SegmentIdentifier const& seg_id, int to_index,
+ RangeOut& current_output)
+ {
+
+ BOOST_ASSERT
+ (
+ seg_id.multi_index >= 0
+ && seg_id.multi_index < int(boost::size(multi_geometry))
+ );
+
+ // Call the single-version
+ Policy::apply(multi_geometry[seg_id.multi_index],
+ seg_id, to_index, current_output);
+ }
+};
+
+
+}} // namespace detail::copy_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename MultiPolygon,
+ bool Reverse,
+ typename SegmentIdentifier,
+ typename RangeOut
+>
+struct copy_segments
+ <
+ multi_polygon_tag,
+ MultiPolygon,
+ Reverse,
+ SegmentIdentifier,
+ RangeOut
+ >
+ : detail::copy_segments::copy_segments_multi
+ <
+ MultiPolygon,
+ SegmentIdentifier,
+ RangeOut,
+ detail::copy_segments::copy_segments_polygon
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ Reverse,
+ SegmentIdentifier,
+ RangeOut
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp b/src/boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp
new file mode 100644
index 0000000..e23acf9
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp
@@ -0,0 +1,54 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
+
+
+#include <boost/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
+#include <boost/geometry/multi/core/ring_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+template<>
+struct get_ring<multi_polygon_tag>
+{
+ template<typename MultiPolygon>
+ static inline typename ring_type<MultiPolygon>::type const& apply(
+ ring_identifier const& id,
+ MultiPolygon const& multi_polygon)
+ {
+ BOOST_ASSERT
+ (
+ id.multi_index >= 0
+ && id.multi_index < int(boost::size(multi_polygon))
+ );
+ return get_ring<polygon_tag>::apply(id,
+ multi_polygon[id.multi_index]);
+ }
+};
+
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_RING_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp b/src/boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp
new file mode 100644
index 0000000..1ee03cc
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp
@@ -0,0 +1,111 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
+
+
+#include <boost/geometry/multi/core/ring_type.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
+
+#include <boost/geometry/multi/algorithms/distance.hpp>
+#include <boost/geometry/multi/views/detail/range_type.hpp>
+
+#include <boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp>
+#include <boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace get_turns
+{
+
+template
+<
+ typename Multi, typename Box,
+ bool Reverse, bool ReverseBox,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns_multi_polygon_cs
+{
+ static inline void apply(
+ int source_id1, Multi const& multi,
+ int source_id2, Box const& box,
+ Turns& turns, InterruptPolicy& interrupt_policy)
+ {
+ typedef typename boost::range_iterator
+ <
+ Multi const
+ >::type iterator_type;
+
+ int i = 0;
+ for (iterator_type it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it, ++i)
+ {
+ // Call its single version
+ get_turns_polygon_cs
+ <
+ typename boost::range_value<Multi>::type, Box,
+ Reverse, ReverseBox,
+ Turns, TurnPolicy, InterruptPolicy
+ >::apply(source_id1, *it, source_id2, box,
+ turns, interrupt_policy, i);
+ }
+ }
+};
+
+}} // namespace detail::get_turns
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename MultiPolygon,
+ typename Box,
+ bool ReverseMultiPolygon, bool ReverseBox,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct get_turns
+ <
+ multi_polygon_tag, box_tag,
+ MultiPolygon, Box,
+ ReverseMultiPolygon, ReverseBox,
+ Turns,
+ TurnPolicy, InterruptPolicy
+ >
+ : detail::get_turns::get_turns_multi_polygon_cs
+ <
+ MultiPolygon, Box,
+ ReverseMultiPolygon, ReverseBox,
+ Turns,
+ TurnPolicy, InterruptPolicy
+ >
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp b/src/boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp
new file mode 100644
index 0000000..4636187
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp
@@ -0,0 +1,62 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay
+{
+
+namespace dispatch
+{
+
+ template <typename Multi>
+ struct select_rings<multi_polygon_tag, Multi>
+ {
+ template <typename Geometry, typename Map>
+ static inline void apply(Multi const& multi, Geometry const& geometry,
+ ring_identifier id, Map& map, bool midpoint)
+ {
+ typedef typename boost::range_iterator
+ <
+ Multi const
+ >::type iterator_type;
+
+ typedef select_rings<polygon_tag, typename boost::range_value<Multi>::type> per_polygon;
+
+ id.multi_index = 0;
+ for (iterator_type it = boost::begin(multi); it != boost::end(multi); ++it)
+ {
+ id.ring_index = -1;
+ per_polygon::apply(*it, geometry, id, map, midpoint);
+ id.multi_index++;
+ }
+ }
+ };
+}
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp b/src/boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp
new file mode 100644
index 0000000..57d5ff9
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp
@@ -0,0 +1,56 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
+
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename MultiPolygon,
+ typename Turns,
+ typename TurnPolicy,
+ typename InterruptPolicy
+>
+struct self_get_turn_points
+ <
+ multi_polygon_tag, MultiPolygon,
+ Turns,
+ TurnPolicy, InterruptPolicy
+ >
+ : detail::self_get_turn_points::get_turns
+ <
+ MultiPolygon,
+ Turns,
+ TurnPolicy,
+ InterruptPolicy
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/point_on_border.hpp b/src/boost/geometry/multi/algorithms/detail/point_on_border.hpp
new file mode 100644
index 0000000..ac462ed
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/point_on_border.hpp
@@ -0,0 +1,95 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/algorithms/detail/point_on_border.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace point_on_border
+{
+
+
+template
+<
+ typename Point,
+ typename MultiGeometry,
+ typename Policy
+>
+struct point_on_multi
+{
+ static inline bool apply(Point& point, MultiGeometry const& multi, bool midpoint)
+ {
+ // Take a point on the first multi-geometry
+ // (i.e. the first that is not empty)
+ for (typename boost::range_iterator
+ <
+ MultiGeometry const
+ >::type it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ if (Policy::apply(point, *it, midpoint))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+
+
+
+}} // namespace detail::point_on_border
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template<typename Point, typename Multi>
+struct point_on_border<multi_polygon_tag, Point, Multi>
+ : detail::point_on_border::point_on_multi
+ <
+ Point,
+ Multi,
+ detail::point_on_border::point_on_polygon
+ <
+ Point,
+ typename boost::range_value<Multi>::type
+ >
+ >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp b/src/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp
new file mode 100644
index 0000000..28a4805
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp
@@ -0,0 +1,90 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
+
+
+#include <boost/assert.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/ring_type.hpp>
+#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace section
+{
+
+
+template
+<
+ typename MultiGeometry,
+ typename Section,
+ typename Policy
+>
+struct full_section_multi
+{
+ static inline typename ring_return_type<MultiGeometry const>::type apply(
+ MultiGeometry const& multi, Section const& section)
+ {
+ BOOST_ASSERT
+ (
+ section.ring_id.multi_index >= 0
+ && section.ring_id.multi_index < int(boost::size(multi))
+ );
+
+ return Policy::apply(multi[section.ring_id.multi_index], section);
+ }
+};
+
+
+}} // namespace detail::section
+#endif
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon, typename Section>
+struct range_by_section<multi_polygon_tag, MultiPolygon, Section>
+ : detail::section::full_section_multi
+ <
+ MultiPolygon,
+ Section,
+ detail::section::full_section_polygon
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ Section
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
diff --git a/src/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp b/src/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp
new file mode 100644
index 0000000..16f70c1
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp
@@ -0,0 +1,95 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sectionalize
+{
+
+
+template <typename MultiGeometry, typename Sections, std::size_t DimensionCount, typename Policy>
+struct sectionalize_multi
+{
+ static inline void apply(MultiGeometry const& multi, Sections& sections, ring_identifier ring_id)
+ {
+ ring_id.multi_index = 0;
+ for (typename boost::range_iterator<MultiGeometry const>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it, ++ring_id.multi_index)
+ {
+ Policy::apply(*it, sections, ring_id);
+ }
+ }
+};
+
+
+}} // namespace detail::sectionalize
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+ typename MultiPolygon,
+ bool Reverse,
+ typename Sections,
+ std::size_t DimensionCount,
+ std::size_t MaxCount
+>
+struct sectionalize<multi_polygon_tag, MultiPolygon, Reverse, Sections, DimensionCount, MaxCount>
+ : detail::sectionalize::sectionalize_multi
+ <
+ MultiPolygon,
+ Sections,
+ DimensionCount,
+ detail::sectionalize::sectionalize_polygon
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ Reverse,
+ Sections,
+ DimensionCount,
+ MaxCount
+ >
+ >
+
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
diff --git a/src/boost/geometry/multi/algorithms/distance.hpp b/src/boost/geometry/multi/algorithms/distance.hpp
new file mode 100644
index 0000000..8acb3f9
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/distance.hpp
@@ -0,0 +1,157 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP
+
+
+#include <boost/numeric/conversion/bounds.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/geometry_id.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/multi/algorithms/num_points.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance
+{
+
+
+template<typename Geometry, typename MultiGeometry, typename Strategy>
+struct distance_single_to_multi
+ : private dispatch::distance
+ <
+ Geometry,
+ typename range_value<MultiGeometry>::type,
+ Strategy
+ >
+{
+ typedef typename strategy::distance::services::return_type<Strategy>::type return_type;
+
+ static inline return_type apply(Geometry const& geometry,
+ MultiGeometry const& multi,
+ Strategy const& strategy)
+ {
+ return_type mindist = return_type();
+ bool first = true;
+
+ for(typename range_iterator<MultiGeometry const>::type it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it, first = false)
+ {
+ return_type dist = dispatch::distance
+ <
+ Geometry,
+ typename range_value<MultiGeometry>::type,
+ Strategy
+ >::apply(geometry, *it, strategy);
+
+ if (first || dist < mindist)
+ {
+ mindist = dist;
+ }
+ }
+
+ return mindist;
+ }
+};
+
+template<typename Multi1, typename Multi2, typename Strategy>
+struct distance_multi_to_multi
+ : private distance_single_to_multi
+ <
+ typename range_value<Multi1>::type,
+ Multi2,
+ Strategy
+ >
+{
+ typedef typename strategy::distance::services::return_type<Strategy>::type return_type;
+
+ static inline return_type apply(Multi1 const& multi1,
+ Multi2 const& multi2, Strategy const& strategy)
+ {
+ return_type mindist = return_type();
+ bool first = true;
+
+ for(typename range_iterator<Multi1 const>::type it = boost::begin(multi1);
+ it != boost::end(multi1);
+ ++it, first = false)
+ {
+ return_type dist = distance_single_to_multi
+ <
+ typename range_value<Multi1>::type,
+ Multi2,
+ Strategy
+ >::apply(*it, multi2, strategy);
+ if (first || dist < mindist)
+ {
+ mindist = dist;
+ }
+ }
+
+ return mindist;
+ }
+};
+
+
+}} // namespace detail::distance
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename G1,
+ typename G2,
+ typename Strategy,
+ typename SingleGeometryTag
+>
+struct distance
+<
+ G1, G2, Strategy,
+ SingleGeometryTag, multi_tag, strategy_tag_distance_point_point,
+ false
+>
+ : detail::distance::distance_single_to_multi<G1, G2, Strategy>
+{};
+
+template <typename G1, typename G2, typename Strategy>
+struct distance
+<
+ G1, G2, Strategy,
+ multi_tag, multi_tag, strategy_tag_distance_point_point,
+ false
+>
+ : detail::distance::distance_multi_to_multi<G1, G2, Strategy>
+{};
+
+} // namespace dispatch
+#endif
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP
diff --git a/src/boost/geometry/multi/algorithms/envelope.hpp b/src/boost/geometry/multi/algorithms/envelope.hpp
new file mode 100644
index 0000000..1876b5f
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/envelope.hpp
@@ -0,0 +1,117 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP
+
+#include <vector>
+
+#include <boost/range/metafunctions.hpp>
+
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/algorithms/envelope.hpp>
+
+#include <boost/geometry/multi/core/point_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+
+namespace detail { namespace envelope
+{
+
+
+template<typename MultiLinestring, typename Box>
+struct envelope_multi_linestring
+{
+ static inline void apply(MultiLinestring const& mp, Box& mbr)
+ {
+ assign_inverse(mbr);
+ for (typename boost::range_iterator<MultiLinestring const>::type
+ it = mp.begin();
+ it != mp.end();
+ ++it)
+ {
+ envelope_range_additional(*it, mbr);
+ }
+ }
+};
+
+
+// version for multi_polygon: outer ring's of all polygons
+template<typename MultiPolygon, typename Box>
+struct envelope_multi_polygon
+{
+ static inline void apply(MultiPolygon const& mp, Box& mbr)
+ {
+ assign_inverse(mbr);
+ for (typename boost::range_const_iterator<MultiPolygon>::type
+ it = mp.begin();
+ it != mp.end();
+ ++it)
+ {
+ envelope_range_additional(exterior_ring(*it), mbr);
+ }
+ }
+};
+
+
+}} // namespace detail::envelope
+
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Multi, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_point_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_range<Multi, Box>
+{};
+
+template
+<
+ typename Multi, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_linestring_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_multi_linestring<Multi, Box>
+{};
+
+
+template
+<
+ typename Multi, typename Box,
+ typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_polygon_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+ : detail::envelope::envelope_multi_polygon<Multi, Box>
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP
diff --git a/src/boost/geometry/multi/algorithms/equals.hpp b/src/boost/geometry/multi/algorithms/equals.hpp
new file mode 100644
index 0000000..a307eba
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/equals.hpp
@@ -0,0 +1,70 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP
+
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/geometry_id.hpp>
+
+#include <boost/geometry/algorithms/equals.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon1, typename MultiPolygon2>
+struct equals
+ <
+ multi_polygon_tag, multi_polygon_tag,
+ MultiPolygon1, MultiPolygon2,
+ 2
+ >
+ : detail::equals::equals_by_collection
+ <
+ MultiPolygon1, MultiPolygon2,
+ detail::equals::area_check
+ >
+{};
+
+
+template <typename Polygon, typename MultiPolygon>
+struct equals
+ <
+ polygon_tag, multi_polygon_tag,
+ Polygon, MultiPolygon,
+ 2
+ >
+ : detail::equals::equals_by_collection
+ <
+ Polygon, MultiPolygon,
+ detail::equals::area_check
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP
+
diff --git a/src/boost/geometry/multi/algorithms/for_each.hpp b/src/boost/geometry/multi/algorithms/for_each.hpp
new file mode 100644
index 0000000..1be38e0
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/for_each.hpp
@@ -0,0 +1,129 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP
+
+
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+
+
+#include <boost/geometry/algorithms/for_each.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each
+{
+
+// Implementation of multi, for both point and segment,
+// just calling the single version.
+template
+<
+ typename MultiGeometry,
+ typename Functor,
+ bool IsConst,
+ typename Policy
+>
+struct for_each_multi
+{
+ static inline Functor apply(
+ typename add_const_if_c<IsConst, MultiGeometry>::type& multi,
+ Functor f)
+ {
+ for(BOOST_AUTO_TPL(it, boost::begin(multi)); it != boost::end(multi); ++it)
+ {
+ f = Policy::apply(*it, f);
+ }
+ return f;
+ }
+};
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename MultiGeometry,
+ typename Functor,
+ bool IsConst
+>
+struct for_each_point<multi_tag, MultiGeometry, Functor, IsConst>
+ : detail::for_each::for_each_multi
+ <
+ MultiGeometry,
+ Functor,
+ IsConst,
+ // Specify the dispatch of the single-version as policy
+ for_each_point
+ <
+ typename single_tag_of
+ <
+ typename tag<MultiGeometry>::type
+ >::type,
+ typename boost::range_value<MultiGeometry>::type,
+ Functor,
+ IsConst
+ >
+ >
+{};
+
+
+template
+<
+ typename MultiGeometry,
+ typename Functor,
+ bool IsConst
+>
+struct for_each_segment<multi_tag, MultiGeometry, Functor, IsConst>
+ : detail::for_each::for_each_multi
+ <
+ MultiGeometry,
+ Functor,
+ IsConst,
+ // Specify the dispatch of the single-version as policy
+ for_each_segment
+ <
+ typename single_tag_of
+ <
+ typename tag<MultiGeometry>::type
+ >::type,
+ typename boost::range_value<MultiGeometry>::type,
+ Functor,
+ IsConst
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP
diff --git a/src/boost/geometry/multi/algorithms/intersection.hpp b/src/boost/geometry/multi/algorithms/intersection.hpp
new file mode 100644
index 0000000..31e74a7
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/intersection.hpp
@@ -0,0 +1,438 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
+
+
+#include <boost/geometry/multi/core/closure.hpp>
+#include <boost/geometry/multi/core/geometry_id.hpp>
+#include <boost/geometry/multi/core/is_areal.hpp>
+#include <boost/geometry/multi/core/point_order.hpp>
+#include <boost/geometry/multi/algorithms/covered_by.hpp>
+#include <boost/geometry/multi/algorithms/envelope.hpp>
+#include <boost/geometry/multi/algorithms/num_points.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp>
+#include <boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp>
+#include <boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp>
+
+#include <boost/geometry/algorithms/intersection.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection
+{
+
+
+template
+<
+ typename MultiLinestring1, typename MultiLinestring2,
+ typename OutputIterator, typename PointOut,
+ typename Strategy
+>
+struct intersection_multi_linestring_multi_linestring_point
+{
+ static inline OutputIterator apply(MultiLinestring1 const& ml1,
+ MultiLinestring2 const& ml2, OutputIterator out,
+ Strategy const& strategy)
+ {
+ // Note, this loop is quadratic w.r.t. number of linestrings per input.
+ // Future Enhancement: first do the sections of each, then intersect.
+ for (typename boost::range_iterator
+ <
+ MultiLinestring1 const
+ >::type it1 = boost::begin(ml1);
+ it1 != boost::end(ml1);
+ ++it1)
+ {
+ for (typename boost::range_iterator
+ <
+ MultiLinestring2 const
+ >::type it2 = boost::begin(ml2);
+ it2 != boost::end(ml2);
+ ++it2)
+ {
+ out = intersection_linestring_linestring_point
+ <
+ typename boost::range_value<MultiLinestring1>::type,
+ typename boost::range_value<MultiLinestring2>::type,
+ OutputIterator, PointOut, Strategy
+ >::apply(*it1, *it2, out, strategy);
+ }
+ }
+
+ return out;
+ }
+};
+
+
+template
+<
+ typename Linestring, typename MultiLinestring,
+ typename OutputIterator, typename PointOut,
+ typename Strategy
+>
+struct intersection_linestring_multi_linestring_point
+{
+ static inline OutputIterator apply(Linestring const& linestring,
+ MultiLinestring const& ml, OutputIterator out,
+ Strategy const& strategy)
+ {
+ for (typename boost::range_iterator
+ <
+ MultiLinestring const
+ >::type it = boost::begin(ml);
+ it != boost::end(ml);
+ ++it)
+ {
+ out = intersection_linestring_linestring_point
+ <
+ Linestring,
+ typename boost::range_value<MultiLinestring>::type,
+ OutputIterator, PointOut, Strategy
+ >::apply(linestring, *it, out, strategy);
+ }
+
+ return out;
+ }
+};
+
+
+// This loop is quite similar to the loop above, but beacuse the iterator
+// is second (above) or first (below) argument, it is not trivial to merge them.
+template
+<
+ typename MultiLinestring, typename Areal,
+ bool ReverseAreal,
+ typename OutputIterator, typename LineStringOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_of_multi_linestring_with_areal
+{
+ static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ for (typename boost::range_iterator
+ <
+ MultiLinestring const
+ >::type it = boost::begin(ml);
+ it != boost::end(ml);
+ ++it)
+ {
+ out = intersection_of_linestring_with_areal
+ <
+ typename boost::range_value<MultiLinestring>::type,
+ Areal, ReverseAreal,
+ OutputIterator, LineStringOut, OverlayType, Strategy
+ >::apply(*it, areal, out, strategy);
+ }
+
+ return out;
+
+ }
+};
+
+// This one calls the one above with reversed arguments
+template
+<
+ typename Areal, typename MultiLinestring,
+ bool ReverseAreal,
+ typename OutputIterator, typename LineStringOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_of_areal_with_multi_linestring
+{
+ static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
+ OutputIterator out,
+ Strategy const& strategy)
+ {
+ return intersection_of_multi_linestring_with_areal
+ <
+ MultiLinestring, Areal, ReverseAreal,
+ OutputIterator, LineStringOut,
+ OverlayType,
+ Strategy
+ >::apply(ml, areal, out, strategy);
+ }
+};
+
+
+
+template
+<
+ typename MultiLinestring, typename Box,
+ typename OutputIterator, typename LinestringOut,
+ typename Strategy
+>
+struct clip_multi_linestring
+{
+ static inline OutputIterator apply(MultiLinestring const& multi_linestring,
+ Box const& box, OutputIterator out, Strategy const& )
+ {
+ typedef typename point_type<LinestringOut>::type point_type;
+ strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
+ for (typename boost::range_iterator<MultiLinestring const>::type it
+ = boost::begin(multi_linestring);
+ it != boost::end(multi_linestring); ++it)
+ {
+ out = detail::intersection::clip_range_with_box
+ <LinestringOut>(box, *it, out, lb_strategy);
+ }
+ return out;
+ }
+};
+
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Linear
+template
+<
+ typename MultiLinestring1, typename MultiLinestring2,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ multi_linestring_tag, multi_linestring_tag, point_tag,
+ false, false, false,
+ MultiLinestring1, MultiLinestring2,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_multi_linestring_multi_linestring_point
+ <
+ MultiLinestring1, MultiLinestring2,
+ OutputIterator, GeometryOut,
+ Strategy
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename MultiLinestring,
+ typename OutputIterator, typename GeometryOut,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ linestring_tag, multi_linestring_tag, point_tag,
+ false, false, false,
+ Linestring, MultiLinestring,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_linestring_multi_linestring_point
+ <
+ Linestring, MultiLinestring,
+ OutputIterator, GeometryOut,
+ Strategy
+ >
+{};
+
+
+template
+<
+ typename MultiLinestring, typename Box,
+ bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ multi_linestring_tag, box_tag, linestring_tag,
+ false, true, false,
+ MultiLinestring, Box,
+ Reverse1, Reverse2, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::clip_multi_linestring
+ <
+ MultiLinestring, Box,
+ OutputIterator, GeometryOut,
+ Strategy
+ >
+{};
+
+
+template
+<
+ typename Linestring, typename MultiPolygon,
+ bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ linestring_tag, multi_polygon_tag, linestring_tag,
+ false, true, false,
+ Linestring, MultiPolygon,
+ ReverseLinestring, ReverseMultiPolygon, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_of_linestring_with_areal
+ <
+ Linestring, MultiPolygon,
+ ReverseMultiPolygon,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{};
+
+
+// Derives from areal/mls because runtime arguments are in that order.
+// areal/mls reverses it itself to mls/areal
+template
+<
+ typename Polygon, typename MultiLinestring,
+ bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ polygon_tag, multi_linestring_tag, linestring_tag,
+ true, false, false,
+ Polygon, MultiLinestring,
+ ReversePolygon, ReverseMultiLinestring, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_of_areal_with_multi_linestring
+ <
+ Polygon, MultiLinestring,
+ ReversePolygon,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{};
+
+
+template
+<
+ typename MultiLinestring, typename Ring,
+ bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ multi_linestring_tag, ring_tag, linestring_tag,
+ false, true, false,
+ MultiLinestring, Ring,
+ ReverseMultiLinestring, ReverseRing, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_of_multi_linestring_with_areal
+ <
+ MultiLinestring, Ring,
+ ReverseRing,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{};
+
+template
+<
+ typename MultiLinestring, typename Polygon,
+ bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ multi_linestring_tag, polygon_tag, linestring_tag,
+ false, true, false,
+ MultiLinestring, Polygon,
+ ReverseMultiLinestring, ReverseRing, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_of_multi_linestring_with_areal
+ <
+ MultiLinestring, Polygon,
+ ReverseRing,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{};
+
+
+
+template
+<
+ typename MultiLinestring, typename MultiPolygon,
+ bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut,
+ typename OutputIterator, typename GeometryOut,
+ overlay_type OverlayType,
+ typename Strategy
+>
+struct intersection_insert
+ <
+ multi_linestring_tag, multi_polygon_tag, linestring_tag,
+ false, true, false,
+ MultiLinestring, MultiPolygon,
+ ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ > : detail::intersection::intersection_of_multi_linestring_with_areal
+ <
+ MultiLinestring, MultiPolygon,
+ ReverseMultiPolygon,
+ OutputIterator, GeometryOut,
+ OverlayType,
+ Strategy
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
+
diff --git a/src/boost/geometry/multi/algorithms/length.hpp b/src/boost/geometry/multi/algorithms/length.hpp
new file mode 100644
index 0000000..51ff9ef
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/length.hpp
@@ -0,0 +1,57 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/algorithms/length.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/algorithms/detail/multi_sum.hpp>
+#include <boost/geometry/multi/algorithms/num_points.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiLinestring, typename Strategy>
+struct length<multi_linestring_tag, MultiLinestring, Strategy>
+ : detail::multi_sum
+ <
+ typename default_length_result<MultiLinestring>::type,
+ MultiLinestring,
+ Strategy,
+ detail::length::range_length
+ <
+ typename boost::range_value<MultiLinestring>::type,
+ Strategy,
+ closed // no need to close it explicitly
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP
diff --git a/src/boost/geometry/multi/algorithms/num_geometries.hpp b/src/boost/geometry/multi/algorithms/num_geometries.hpp
new file mode 100644
index 0000000..213339a
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/num_geometries.hpp
@@ -0,0 +1,51 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP
+
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/num_geometries.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiGeometry>
+struct num_geometries<multi_tag, MultiGeometry>
+{
+ static inline std::size_t apply(MultiGeometry const& multi_geometry)
+ {
+ return boost::size(multi_geometry);
+ }
+};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP
diff --git a/src/boost/geometry/multi/algorithms/num_interior_rings.hpp b/src/boost/geometry/multi/algorithms/num_interior_rings.hpp
new file mode 100644
index 0000000..87b0bde
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/num_interior_rings.hpp
@@ -0,0 +1,61 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon>
+struct num_interior_rings<multi_polygon_tag, MultiPolygon>
+{
+ static inline std::size_t apply(MultiPolygon const& multi_polygon)
+ {
+ std::size_t n = 0;
+ for (typename boost::range_iterator<MultiPolygon const>::type
+ it = boost::begin(multi_polygon);
+ it != boost::end(multi_polygon);
+ ++it)
+ {
+ n += geometry::num_interior_rings(*it);
+ }
+ return n;
+ }
+
+};
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
diff --git a/src/boost/geometry/multi/algorithms/num_points.hpp b/src/boost/geometry/multi/algorithms/num_points.hpp
new file mode 100644
index 0000000..5ea5385
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/num_points.hpp
@@ -0,0 +1,81 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/algorithms/num_points.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace num_points
+{
+
+
+template <typename MultiGeometry>
+struct multi_count
+{
+ static inline size_t apply(MultiGeometry const& geometry, bool add_for_open)
+ {
+ typedef typename boost::range_value<MultiGeometry>::type geometry_type;
+ typedef typename boost::range_iterator
+ <
+ MultiGeometry const
+ >::type iterator_type;
+
+ std::size_t n = 0;
+ for (iterator_type it = boost::begin(geometry);
+ it != boost::end(geometry);
+ ++it)
+ {
+ n += dispatch::num_points
+ <
+ typename tag<geometry_type>::type,
+ geometry_type
+ >::apply(*it, add_for_open);
+ }
+ return n;
+ }
+};
+
+
+}} // namespace detail::num_points
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry>
+struct num_points<multi_tag, Geometry>
+ : detail::num_points::multi_count<Geometry> {};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
diff --git a/src/boost/geometry/multi/algorithms/perimeter.hpp b/src/boost/geometry/multi/algorithms/perimeter.hpp
new file mode 100644
index 0000000..147f6fc
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/perimeter.hpp
@@ -0,0 +1,56 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/algorithms/perimeter.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+#include <boost/geometry/multi/algorithms/detail/multi_sum.hpp>
+#include <boost/geometry/multi/algorithms/num_points.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+template <typename MultiPolygon, typename Strategy>
+struct perimeter<multi_polygon_tag, MultiPolygon, Strategy>
+ : detail::multi_sum
+ <
+ typename default_length_result<MultiPolygon>::type,
+ MultiPolygon,
+ Strategy,
+ perimeter
+ <
+ polygon_tag,
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >
+{};
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP
diff --git a/src/boost/geometry/multi/algorithms/reverse.hpp b/src/boost/geometry/multi/algorithms/reverse.hpp
new file mode 100644
index 0000000..f8a9442
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/reverse.hpp
@@ -0,0 +1,69 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/algorithms/reverse.hpp>
+#include <boost/geometry/multi/algorithms/detail/modify.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry>
+struct reverse<multi_linestring_tag, Geometry>
+ : detail::multi_modify
+ <
+ Geometry,
+ detail::reverse::range_reverse
+ <
+ typename boost::range_value<Geometry>::type
+ >
+ >
+{};
+
+
+template <typename Geometry>
+struct reverse<multi_polygon_tag, Geometry>
+ : detail::multi_modify
+ <
+ Geometry,
+ detail::reverse::polygon_reverse
+ <
+ typename boost::range_value<Geometry>::type
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP
diff --git a/src/boost/geometry/multi/algorithms/simplify.hpp b/src/boost/geometry/multi/algorithms/simplify.hpp
new file mode 100644
index 0000000..dc3c7b5
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/simplify.hpp
@@ -0,0 +1,117 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+#include <boost/geometry/multi/algorithms/clear.hpp>
+#include <boost/geometry/algorithms/simplify.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace simplify
+{
+
+template<typename MultiGeometry, typename Strategy, typename Policy>
+struct simplify_multi
+{
+ static inline void apply(MultiGeometry const& multi, MultiGeometry& out,
+ double max_distance, Strategy const& strategy)
+ {
+ traits::resize<MultiGeometry>::apply(out, boost::size(multi));
+
+ typename boost::range_iterator<MultiGeometry>::type it_out
+ = boost::begin(out);
+ for (typename boost::range_iterator<MultiGeometry const>::type it_in
+ = boost::begin(multi);
+ it_in != boost::end(multi);
+ ++it_in, ++it_out)
+ {
+ Policy::apply(*it_in, *it_out, max_distance, strategy);
+ }
+ }
+};
+
+
+
+}} // namespace detail::simplify
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiPoint, typename Strategy>
+struct simplify<multi_point_tag, MultiPoint, Strategy>
+ : detail::simplify::simplify_copy
+ <
+ MultiPoint,
+ Strategy
+ >
+
+{};
+
+
+template <typename MultiLinestring, typename Strategy>
+struct simplify<multi_linestring_tag, MultiLinestring, Strategy>
+ : detail::simplify::simplify_multi
+ <
+ MultiLinestring,
+ Strategy,
+ detail::simplify::simplify_range
+ <
+ typename boost::range_value<MultiLinestring>::type,
+ Strategy,
+ 2
+ >
+ >
+
+{};
+
+
+template <typename MultiPolygon, typename Strategy>
+struct simplify<multi_polygon_tag, MultiPolygon, Strategy>
+ : detail::simplify::simplify_multi
+ <
+ MultiPolygon,
+ Strategy,
+ detail::simplify::simplify_polygon
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >
+
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP
diff --git a/src/boost/geometry/multi/algorithms/transform.hpp b/src/boost/geometry/multi/algorithms/transform.hpp
new file mode 100644
index 0000000..0992677
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/transform.hpp
@@ -0,0 +1,102 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_TRANSFORM_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_TRANSFORM_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace transform
+{
+
+/*!
+ \brief Is able to transform any multi-geometry, calling the single-version as policy
+*/
+template <typename Multi1, typename Multi2, typename Policy>
+struct transform_multi
+{
+ template <typename S>
+ static inline bool apply(Multi1 const& multi1, Multi2& multi2, S const& strategy)
+ {
+ traits::resize<Multi2>::apply(multi2, boost::size(multi1));
+
+ typename boost::range_iterator<Multi1 const>::type it1
+ = boost::begin(multi1);
+ typename boost::range_iterator<Multi2>::type it2
+ = boost::begin(multi2);
+
+ for (; it1 != boost::end(multi1); ++it1, ++it2)
+ {
+ if (! Policy::apply(*it1, *it2, strategy))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
+
+
+}} // namespace detail::transform
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Multi1, typename Multi2, typename Strategy>
+struct transform
+ <
+ multi_tag, multi_tag,
+ Multi1, Multi2,
+ Strategy
+ >
+ : detail::transform::transform_multi
+ <
+ Multi1,
+ Multi2,
+ transform
+ <
+ typename single_tag_of
+ <
+ typename tag<Multi1>::type
+ >::type,
+ typename single_tag_of
+ <
+ typename tag<Multi2>::type
+ >::type,
+ typename boost::range_value<Multi1>::type,
+ typename boost::range_value<Multi2>::type,
+ Strategy
+ >
+ >
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_TRANSFORM_HPP
diff --git a/src/boost/geometry/multi/algorithms/unique.hpp b/src/boost/geometry/multi/algorithms/unique.hpp
new file mode 100644
index 0000000..5067e71
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/unique.hpp
@@ -0,0 +1,102 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_UNIQUE_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_UNIQUE_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/unique.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace unique
+{
+
+
+template <typename MultiGeometry, typename ComparePolicy, typename Policy>
+struct multi_unique
+{
+ static inline void apply(MultiGeometry& multi, ComparePolicy const& compare)
+ {
+ for (typename boost::range_iterator<MultiGeometry>::type
+ it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ Policy::apply(*it, compare);
+ }
+ }
+};
+
+
+}} // namespace detail::unique
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// For points, unique is not applicable and does nothing
+// (Note that it is not "spatially unique" but that it removes duplicate coordinates,
+// like std::unique does). Spatially unique is "dissolve" which can (or will be)
+// possible for multi-points as well, removing points at the same location.
+
+
+template <typename MultiLineString, typename ComparePolicy>
+struct unique<multi_linestring_tag, MultiLineString, ComparePolicy>
+ : detail::unique::multi_unique
+ <
+ MultiLineString,
+ ComparePolicy,
+ detail::unique::range_unique
+ <
+ typename boost::range_value<MultiLineString>::type,
+ ComparePolicy
+ >
+ >
+{};
+
+
+template <typename MultiPolygon, typename ComparePolicy>
+struct unique<multi_polygon_tag, MultiPolygon, ComparePolicy>
+ : detail::unique::multi_unique
+ <
+ MultiPolygon,
+ ComparePolicy,
+ detail::unique::polygon_unique
+ <
+ typename boost::range_value<MultiPolygon>::type,
+ ComparePolicy
+ >
+ >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_UNIQUE_HPP
diff --git a/src/boost/geometry/multi/algorithms/within.hpp b/src/boost/geometry/multi/algorithms/within.hpp
new file mode 100644
index 0000000..a3ec751
--- /dev/null
+++ b/src/boost/geometry/multi/algorithms/within.hpp
@@ -0,0 +1,104 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_WITHIN_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_WITHIN_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/algorithms/within.hpp>
+#include <boost/geometry/multi/core/closure.hpp>
+#include <boost/geometry/multi/core/point_order.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within
+{
+
+
+template
+<
+ typename Geometry,
+ typename MultiGeometry,
+ typename Strategy,
+ typename Policy
+>
+struct geometry_multi_within_code
+{
+ static inline int apply(Geometry const& geometry,
+ MultiGeometry const& multi,
+ Strategy const& strategy)
+ {
+ for (typename boost::range_iterator<MultiGeometry const>::type it
+ = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ // Geometry coding on multi: 1 (within) if within one of them;
+ // 0 (touch) if on border of one of them
+ int const code = Policy::apply(geometry, *it, strategy);
+ if (code != -1)
+ {
+ return code;
+ }
+ }
+ return -1;
+ }
+};
+
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Point, typename MultiPolygon>
+struct within<Point, MultiPolygon, point_tag, multi_polygon_tag>
+{
+ template <typename Strategy>
+ static inline bool apply(Point const& point,
+ MultiPolygon const& multi_polygon, Strategy const& strategy)
+ {
+ return detail::within::geometry_multi_within_code
+ <
+ Point,
+ MultiPolygon,
+ Strategy,
+ detail::within::point_in_polygon
+ <
+ Point,
+ typename boost::range_value<MultiPolygon>::type,
+ order_as_direction
+ <
+ geometry::point_order<MultiPolygon>::value
+ >::value,
+ geometry::closure<MultiPolygon>::value,
+ Strategy
+ >
+ >::apply(point, multi_polygon, strategy) == 1;
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_WITHIN_HPP
diff --git a/src/boost/geometry/multi/core/closure.hpp b/src/boost/geometry/multi/core/closure.hpp
new file mode 100644
index 0000000..3964db2
--- /dev/null
+++ b/src/boost/geometry/multi/core/closure.hpp
@@ -0,0 +1,58 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_CORE_CLOSURE_HPP
+#define BOOST_GEOMETRY_MULTI_CORE_CLOSURE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Multi>
+struct closure<multi_point_tag, Multi> : public core_detail::closure::closed {};
+
+template <typename Multi>
+struct closure<multi_linestring_tag, Multi> : public core_detail::closure::closed {};
+
+// Specialization for polygon: the closure is the closure of its rings
+template <typename MultiPolygon>
+struct closure<multi_polygon_tag, MultiPolygon>
+{
+ static const closure_selector value = core_dispatch::closure
+ <
+ polygon_tag,
+ typename boost::range_value<MultiPolygon>::type
+ >::value ;
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_CORE_CLOSURE_HPP
diff --git a/src/boost/geometry/multi/core/geometry_id.hpp b/src/boost/geometry/multi/core/geometry_id.hpp
new file mode 100644
index 0000000..9d69cb2
--- /dev/null
+++ b/src/boost/geometry/multi/core/geometry_id.hpp
@@ -0,0 +1,56 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_CORE_GEOMETRY_ID_HPP
+#define BOOST_GEOMETRY_MULTI_CORE_GEOMETRY_ID_HPP
+
+
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/core/geometry_id.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <>
+struct geometry_id<multi_point_tag> : boost::mpl::int_<4> {};
+
+
+template <>
+struct geometry_id<multi_linestring_tag> : boost::mpl::int_<5> {};
+
+
+template <>
+struct geometry_id<multi_polygon_tag> : boost::mpl::int_<6> {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_CORE_GEOMETRY_ID_HPP
diff --git a/src/boost/geometry/multi/core/interior_rings.hpp b/src/boost/geometry/multi/core/interior_rings.hpp
new file mode 100644
index 0000000..5a200d4
--- /dev/null
+++ b/src/boost/geometry/multi/core/interior_rings.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_CORE_INTERIOR_RINGS_HPP
+#define BOOST_GEOMETRY_MULTI_CORE_INTERIOR_RINGS_HPP
+
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename MultiPolygon>
+struct interior_type<multi_polygon_tag, MultiPolygon>
+{
+ typedef typename core_dispatch::interior_type
+ <
+ polygon_tag,
+ typename boost::range_value<MultiPolygon>::type
+ >::type type;
+};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_CORE_INTERIOR_RINGS_HPP
diff --git a/src/boost/geometry/multi/core/is_areal.hpp b/src/boost/geometry/multi/core/is_areal.hpp
new file mode 100644
index 0000000..ad8daeb
--- /dev/null
+++ b/src/boost/geometry/multi/core/is_areal.hpp
@@ -0,0 +1,43 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_CORE_IS_AREAL_HPP
+#define BOOST_GEOMETRY_MULTI_CORE_IS_AREAL_HPP
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <boost/geometry/core/is_areal.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <> struct is_areal<multi_polygon_tag> : boost::true_type {};
+
+} // namespace core_dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_CORE_IS_AREAL_HPP
diff --git a/src/boost/geometry/multi/core/point_order.hpp b/src/boost/geometry/multi/core/point_order.hpp
new file mode 100644
index 0000000..6b08468
--- /dev/null
+++ b/src/boost/geometry/multi/core/point_order.hpp
@@ -0,0 +1,57 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_CORE_POINT_ORDER_HPP
+#define BOOST_GEOMETRY_MULTI_CORE_POINT_ORDER_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Multi>
+struct point_order<multi_point_tag, Multi>
+ : public detail::point_order::clockwise {};
+
+template <typename Multi>
+struct point_order<multi_linestring_tag, Multi>
+ : public detail::point_order::clockwise {};
+
+
+// Specialization for multi_polygon: the order is the order of its polygons
+template <typename MultiPolygon>
+struct point_order<multi_polygon_tag, MultiPolygon>
+{
+ static const order_selector value = core_dispatch::point_order
+ <
+ polygon_tag,
+ typename boost::range_value<MultiPolygon>::type
+ >::value ;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_CORE_POINT_ORDER_HPP
diff --git a/src/boost/geometry/multi/core/point_type.hpp b/src/boost/geometry/multi/core/point_type.hpp
new file mode 100644
index 0000000..3c77e97
--- /dev/null
+++ b/src/boost/geometry/multi/core/point_type.hpp
@@ -0,0 +1,64 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_CORE_POINT_TYPE_HPP
+#define BOOST_GEOMETRY_MULTI_CORE_POINT_TYPE_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename MultiPoint>
+struct point_type<multi_point_tag, MultiPoint>
+{
+ typedef typename boost::range_value<MultiPoint>::type type;
+};
+
+
+template <typename MultiLinestring>
+struct point_type<multi_linestring_tag, MultiLinestring>
+{
+ typedef typename point_type<linestring_tag,
+ typename boost::range_value<MultiLinestring>::type>::type type;
+};
+
+
+
+template <typename MultiPolygon>
+struct point_type<multi_polygon_tag, MultiPolygon>
+{
+ typedef typename point_type<polygon_tag,
+ typename boost::range_value<MultiPolygon>::type>::type type;
+};
+
+
+}
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_CORE_POINT_TYPE_HPP
diff --git a/src/boost/geometry/multi/core/ring_type.hpp b/src/boost/geometry/multi/core/ring_type.hpp
new file mode 100644
index 0000000..faafaed
--- /dev/null
+++ b/src/boost/geometry/multi/core/ring_type.hpp
@@ -0,0 +1,66 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_CORE_RING_TYPE_HPP
+#define BOOST_GEOMETRY_MULTI_CORE_RING_TYPE_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename MultiPolygon>
+struct ring_return_type<multi_polygon_tag, MultiPolygon>
+{
+ typedef typename ring_return_type
+ <
+ polygon_tag,
+ typename mpl::if_
+ <
+ boost::is_const<MultiPolygon>,
+ typename boost::range_value<MultiPolygon>::type const,
+ typename boost::range_value<MultiPolygon>::type
+ >::type
+ >::type type;
+};
+
+
+template <typename MultiPolygon>
+struct ring_type<multi_polygon_tag, MultiPolygon>
+{
+ typedef typename boost::remove_reference
+ <
+ typename ring_return_type<multi_polygon_tag, MultiPolygon>::type
+ >::type type;
+};
+
+
+} // namespace core_dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_CORE_RING_TYPE_HPP
diff --git a/src/boost/geometry/multi/core/tags.hpp b/src/boost/geometry/multi/core/tags.hpp
new file mode 100644
index 0000000..dcfca65
--- /dev/null
+++ b/src/boost/geometry/multi/core/tags.hpp
@@ -0,0 +1,71 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_CORE_TAGS_HPP
+#define BOOST_GEOMETRY_MULTI_CORE_TAGS_HPP
+
+#include <boost/geometry/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+/// OGC Multi point identifying tag
+struct multi_point_tag : multi_tag, pointlike_tag {};
+
+/// OGC Multi linestring identifying tag
+struct multi_linestring_tag : multi_tag, linear_tag {};
+
+/// OGC Multi polygon identifying tag
+struct multi_polygon_tag : multi_tag, polygonal_tag {};
+
+/// OGC Geometry Collection identifying tag
+struct geometry_collection_tag : multi_tag {};
+
+
+
+
+/*!
+\brief Meta-function to get for a tag of a multi-geometry
+ the tag of the corresponding single-geometry
+*/
+template <typename Tag>
+struct single_tag_of
+{};
+
+#ifndef DOXYGEN_NO_DETAIL
+
+template <>
+struct single_tag_of<multi_point_tag>
+{
+ typedef point_tag type;
+};
+
+template <>
+struct single_tag_of<multi_linestring_tag>
+{
+ typedef linestring_tag type;
+};
+
+template <>
+struct single_tag_of<multi_polygon_tag>
+{
+ typedef polygon_tag type;
+};
+
+#endif
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_CORE_TAGS_HPP
diff --git a/src/boost/geometry/multi/core/topological_dimension.hpp b/src/boost/geometry/multi/core/topological_dimension.hpp
new file mode 100644
index 0000000..55118f1
--- /dev/null
+++ b/src/boost/geometry/multi/core/topological_dimension.hpp
@@ -0,0 +1,52 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_TOPOLOGICAL_DIMENSION_HPP
+#define BOOST_GEOMETRY_MULTI_TOPOLOGICAL_DIMENSION_HPP
+
+
+#include <boost/mpl/int.hpp>
+
+
+#include <boost/geometry/core/topological_dimension.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <>
+struct top_dim<multi_point_tag> : boost::mpl::int_<0> {};
+
+
+template <>
+struct top_dim<multi_linestring_tag> : boost::mpl::int_<1> {};
+
+
+template <>
+struct top_dim<multi_polygon_tag> : boost::mpl::int_<2> {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif
diff --git a/src/boost/geometry/multi/geometries/concepts/check.hpp b/src/boost/geometry/multi/geometries/concepts/check.hpp
new file mode 100644
index 0000000..18f4ff0
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/concepts/check.hpp
@@ -0,0 +1,83 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_CHECK_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_CHECK_HPP
+
+
+
+#include <boost/type_traits/is_const.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+#include <boost/geometry/multi/geometries/concepts/multi_point_concept.hpp>
+#include <boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp>
+#include <boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry>
+struct check<multi_point_tag, Geometry, true>
+ : detail::concept_check::check<concept::ConstMultiPoint<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_point_tag, Geometry, false>
+ : detail::concept_check::check<concept::MultiPoint<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_linestring_tag, Geometry, true>
+ : detail::concept_check::check<concept::ConstMultiLinestring<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_linestring_tag, Geometry, false>
+ : detail::concept_check::check<concept::MultiLinestring<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_polygon_tag, Geometry, true>
+ : detail::concept_check::check<concept::ConstMultiPolygon<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_polygon_tag, Geometry, false>
+ : detail::concept_check::check<concept::MultiPolygon<Geometry> >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_CHECK_HPP
diff --git a/src/boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp b/src/boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp
new file mode 100644
index 0000000..b0519f0
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp
@@ -0,0 +1,86 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_LINESTRING_CONCEPT_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_LINESTRING_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <boost/geometry/geometries/concepts/linestring_concept.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+\brief multi-linestring concept
+\ingroup concepts
+\par Formal definition:
+The multi linestring concept is defined as following:
+- there must be a specialization of traits::tag defining multi_linestring_tag as
+ type
+- it must behave like a Boost.Range
+- its range value must fulfil the Linestring concept
+
+*/
+template <typename Geometry>
+class MultiLinestring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename boost::range_value<Geometry>::type linestring_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Linestring<linestring_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+ BOOST_CONCEPT_USAGE(MultiLinestring)
+ {
+ }
+#endif
+};
+
+
+/*!
+\brief concept for multi-linestring (const version)
+\ingroup const_concepts
+*/
+template <typename Geometry>
+class ConstMultiLinestring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename boost::range_value<Geometry>::type linestring_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::ConstLinestring<linestring_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+ BOOST_CONCEPT_USAGE(ConstMultiLinestring)
+ {
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_LINESTRING_CONCEPT_HPP
diff --git a/src/boost/geometry/multi/geometries/concepts/multi_point_concept.hpp b/src/boost/geometry/multi/geometries/concepts/multi_point_concept.hpp
new file mode 100644
index 0000000..f5942df
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/concepts/multi_point_concept.hpp
@@ -0,0 +1,85 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POINT_CONCEPT_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POINT_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+\brief MultiPoint concept
+\ingroup concepts
+\par Formal definition:
+The multi point concept is defined as following:
+- there must be a specialization of traits::tag defining multi_point_tag as type
+- it must behave like a Boost.Range
+- its range value must fulfil the Point concept
+
+*/
+template <typename Geometry>
+class MultiPoint
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename boost::range_value<Geometry>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+ BOOST_CONCEPT_USAGE(MultiPoint)
+ {
+ }
+#endif
+};
+
+
+/*!
+\brief concept for multi-point (const version)
+\ingroup const_concepts
+*/
+template <typename Geometry>
+class ConstMultiPoint
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename boost::range_value<Geometry>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+ BOOST_CONCEPT_USAGE(ConstMultiPoint)
+ {
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POINT_CONCEPT_HPP
diff --git a/src/boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp b/src/boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp
new file mode 100644
index 0000000..ca730d4
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp
@@ -0,0 +1,86 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POLYGON_CONCEPT_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POLYGON_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/geometry/geometries/concepts/polygon_concept.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+\brief multi-polygon concept
+\ingroup concepts
+\par Formal definition:
+The multi polygon concept is defined as following:
+- there must be a specialization of traits::tag defining multi_polygon_tag
+ as type
+- it must behave like a Boost.Range
+- its range value must fulfil the Polygon concept
+
+*/
+template <typename Geometry>
+class MultiPolygon
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename boost::range_value<Geometry>::type polygon_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Polygon<polygon_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+ BOOST_CONCEPT_USAGE(MultiPolygon)
+ {
+ }
+#endif
+};
+
+
+/*!
+\brief concept for multi-polygon (const version)
+\ingroup const_concepts
+*/
+template <typename Geometry>
+class ConstMultiPolygon
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+ typedef typename boost::range_value<Geometry>::type polygon_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::ConstPolygon<polygon_type>) );
+ BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+ BOOST_CONCEPT_USAGE(ConstMultiPolygon)
+ {
+ }
+#endif
+};
+
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POLYGON_CONCEPT_HPP
diff --git a/src/boost/geometry/multi/geometries/multi_geometries.hpp b/src/boost/geometry/multi/geometries/multi_geometries.hpp
new file mode 100644
index 0000000..90cf85a
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/multi_geometries.hpp
@@ -0,0 +1,21 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_GEOMETRIES_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_GEOMETRIES_HPP
+
+#include <boost/geometry/multi/geometries/multi_point.hpp>
+#include <boost/geometry/multi/geometries/multi_linestring.hpp>
+#include <boost/geometry/multi/geometries/multi_polygon.hpp>
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_GEOMETRIES_HPP
diff --git a/src/boost/geometry/multi/geometries/multi_linestring.hpp b/src/boost/geometry/multi/geometries/multi_linestring.hpp
new file mode 100644
index 0000000..67d4da0
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/multi_linestring.hpp
@@ -0,0 +1,80 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_LINESTRING_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_LINESTRING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+
+#include <boost/geometry/geometries/concepts/linestring_concept.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+namespace model
+{
+
+/*!
+\brief multi_line, a collection of linestring
+\details Multi-linestring can be used to group lines belonging to each other,
+ e.g. a highway (with interruptions)
+\ingroup geometries
+
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_multi_linestring MultiLineString Concept]
+}
+*/
+template
+<
+ typename LineString,
+ template<typename, typename> class Container = std::vector,
+ template<typename> class Allocator = std::allocator
+>
+class multi_linestring : public Container<LineString, Allocator<LineString> >
+{
+ BOOST_CONCEPT_ASSERT( (concept::Linestring<LineString>) );
+};
+
+
+} // namespace model
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+ typename LineString,
+ template<typename, typename> class Container,
+ template<typename> class Allocator
+>
+struct tag< model::multi_linestring<LineString, Container, Allocator> >
+{
+ typedef multi_linestring_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_LINESTRING_HPP
diff --git a/src/boost/geometry/multi/geometries/multi_point.hpp b/src/boost/geometry/multi/geometries/multi_point.hpp
new file mode 100644
index 0000000..002d8f8
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/multi_point.hpp
@@ -0,0 +1,94 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POINT_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POINT_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+
+/*!
+\brief multi_point, a collection of points
+\ingroup geometries
+\tparam Point \tparam_point
+\tparam Container \tparam_container
+\tparam Allocator \tparam_allocator
+\details Multipoint can be used to group points belonging to each other,
+ e.g. a constellation, or the result set of an intersection
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_multi_point MultiPoint Concept]
+}
+*/
+template
+<
+ typename Point,
+ template<typename, typename> class Container = std::vector,
+ template<typename> class Allocator = std::allocator
+>
+class multi_point : public Container<Point, Allocator<Point> >
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ typedef Container<Point, Allocator<Point> > base_type;
+
+public :
+ /// \constructor_default{multi_point}
+ inline multi_point()
+ : base_type()
+ {}
+
+ /// \constructor_begin_end{multi_point}
+ template <typename Iterator>
+ inline multi_point(Iterator begin, Iterator end)
+ : base_type(begin, end)
+ {}
+};
+
+} // namespace model
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+ typename Point,
+ template<typename, typename> class Container,
+ template<typename> class Allocator
+>
+struct tag< model::multi_point<Point, Container, Allocator> >
+{
+ typedef multi_point_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POINT_HPP
diff --git a/src/boost/geometry/multi/geometries/multi_polygon.hpp b/src/boost/geometry/multi/geometries/multi_polygon.hpp
new file mode 100644
index 0000000..af8d042
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/multi_polygon.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+#include <boost/geometry/geometries/concepts/polygon_concept.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace model
+{
+
+/*!
+\brief multi_polygon, a collection of polygons
+\details Multi-polygon can be used to group polygons belonging to each other,
+ e.g. Hawaii
+\ingroup geometries
+
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_multi_polygon MultiPolygon Concept]
+}
+*/
+template
+<
+ typename Polygon,
+ template<typename, typename> class Container = std::vector,
+ template<typename> class Allocator = std::allocator
+>
+class multi_polygon : public Container<Polygon, Allocator<Polygon> >
+{
+ BOOST_CONCEPT_ASSERT( (concept::Polygon<Polygon>) );
+};
+
+
+} // namespace model
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+ typename Polygon,
+ template<typename, typename> class Container,
+ template<typename> class Allocator
+>
+struct tag< model::multi_polygon<Polygon, Container, Allocator> >
+{
+ typedef multi_polygon_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
diff --git a/src/boost/geometry/multi/geometries/register/multi_linestring.hpp b/src/boost/geometry/multi/geometries/register/multi_linestring.hpp
new file mode 100644
index 0000000..5ececdb
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/register/multi_linestring.hpp
@@ -0,0 +1,59 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_LINESTRING_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_LINESTRING_HPP
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+/*!
+\brief \brief_macro{multi_linestring}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_MULTI_LINESTRING, multi_linestring} The
+ multi_linestring may contain template parameters, which must be specified then.
+\param MultiLineString \param_macro_type{multi_linestring}
+
+\qbk{
+[heading Example]
+[register_multi_linestring]
+[register_multi_linestring_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_MULTI_LINESTRING(MultiLineString) \
+namespace boost { namespace geometry { namespace traits { \
+ template<> struct tag<MultiLineString> { typedef multi_linestring_tag type; }; \
+}}}
+
+
+/*!
+\brief \brief_macro{templated multi_linestring}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_MULTI_LINESTRING_TEMPLATED, templated multi_linestring}
+ \details_macro_templated{multi_linestring, linestring}
+\param MultiLineString \param_macro_type{multi_linestring (without template parameters)}
+
+\qbk{
+[heading Example]
+[register_multi_linestring_templated]
+[register_multi_linestring_templated_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_MULTI_LINESTRING_TEMPLATED(MultiLineString) \
+namespace boost { namespace geometry { namespace traits { \
+ template<typename LineString> struct tag< MultiLineString<LineString> > { typedef multi_linestring_tag type; }; \
+}}}
+
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_LINESTRING_HPP
diff --git a/src/boost/geometry/multi/geometries/register/multi_point.hpp b/src/boost/geometry/multi/geometries/register/multi_point.hpp
new file mode 100644
index 0000000..813f547
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/register/multi_point.hpp
@@ -0,0 +1,59 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POINT_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POINT_HPP
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+/*!
+\brief \brief_macro{multi_point}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_MULTI_POINT, multi_point} The
+ multi_point may contain template parameters, which must be specified then.
+\param MultiPoint \param_macro_type{multi_point}
+
+\qbk{
+[heading Example]
+[register_multi_point]
+[register_multi_point_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_MULTI_POINT(MultiPoint) \
+namespace boost { namespace geometry { namespace traits { \
+ template<> struct tag<MultiPoint> { typedef multi_point_tag type; }; \
+}}}
+
+
+/*!
+\brief \brief_macro{templated multi_point}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_MULTI_POINT_TEMPLATED, templated multi_point}
+ \details_macro_templated{multi_point, point}
+\param MultiPoint \param_macro_type{multi_point (without template parameters)}
+
+\qbk{
+[heading Example]
+[register_multi_point_templated]
+[register_multi_point_templated_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_MULTI_POINT_TEMPLATED(MultiPoint) \
+namespace boost { namespace geometry { namespace traits { \
+ template<typename Point> struct tag< MultiPoint<Point> > { typedef multi_point_tag type; }; \
+}}}
+
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POINT_HPP
diff --git a/src/boost/geometry/multi/geometries/register/multi_polygon.hpp b/src/boost/geometry/multi/geometries/register/multi_polygon.hpp
new file mode 100644
index 0000000..801b98c
--- /dev/null
+++ b/src/boost/geometry/multi/geometries/register/multi_polygon.hpp
@@ -0,0 +1,59 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POLYGON_HPP
+#define BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POLYGON_HPP
+
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+
+/*!
+\brief \brief_macro{multi_polygon}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_MULTI_POLYGON, multi_polygon} The
+ multi_polygon may contain template parameters, which must be specified then.
+\param MultiPolygon \param_macro_type{multi_polygon}
+
+\qbk{
+[heading Example]
+[register_multi_polygon]
+[register_multi_polygon_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_MULTI_POLYGON(MultiPolygon) \
+namespace boost { namespace geometry { namespace traits { \
+ template<> struct tag<MultiPolygon> { typedef multi_polygon_tag type; }; \
+}}}
+
+
+/*!
+\brief \brief_macro{templated multi_polygon}
+\ingroup register
+\details \details_macro{BOOST_GEOMETRY_REGISTER_MULTI_POLYGON_TEMPLATED, templated multi_polygon}
+ \details_macro_templated{multi_polygon, polygon}
+\param MultiPolygon \param_macro_type{multi_polygon (without template parameters)}
+
+\qbk{
+[heading Example]
+[register_multi_polygon_templated]
+[register_multi_polygon_templated_output]
+}
+*/
+#define BOOST_GEOMETRY_REGISTER_MULTI_POLYGON_TEMPLATED(MultiPolygon) \
+namespace boost { namespace geometry { namespace traits { \
+ template<typename Polygon> struct tag< MultiPolygon<Polygon> > { typedef multi_polygon_tag type; }; \
+}}}
+
+
+#endif // BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POLYGON_HPP
diff --git a/src/boost/geometry/multi/io/dsv/write.hpp b/src/boost/geometry/multi/io/dsv/write.hpp
new file mode 100644
index 0000000..be40b5d
--- /dev/null
+++ b/src/boost/geometry/multi/io/dsv/write.hpp
@@ -0,0 +1,83 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_IO_DSV_WRITE_HPP
+#define BOOST_GEOMETRY_MULTI_IO_DSV_WRITE_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/io/dsv/write.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv
+{
+
+template <typename MultiGeometry>
+struct dsv_multi
+{
+ typedef dispatch::dsv
+ <
+ typename single_tag_of
+ <
+ typename tag<MultiGeometry>::type
+ >::type,
+ typename boost::range_value<MultiGeometry>::type
+ > dispatch_one;
+
+ typedef typename boost::range_iterator
+ <
+ MultiGeometry const
+ >::type iterator;
+
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ MultiGeometry const& multi,
+ dsv_settings const& settings)
+ {
+ os << settings.list_open;
+
+ bool first = true;
+ for(iterator it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it, first = false)
+ {
+ os << (first ? "" : settings.list_separator);
+ dispatch_one::apply(os, *it, settings);
+ }
+ os << settings.list_close;
+ }
+};
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry>
+struct dsv<multi_tag, Geometry>
+ : detail::dsv::dsv_multi<Geometry>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_IO_DSV_WRITE_HPP
diff --git a/src/boost/geometry/multi/io/wkt/detail/prefix.hpp b/src/boost/geometry/multi/io/wkt/detail/prefix.hpp
new file mode 100644
index 0000000..37b0797
--- /dev/null
+++ b/src/boost/geometry/multi/io/wkt/detail/prefix.hpp
@@ -0,0 +1,51 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_IO_WKT_DETAIL_PREFIX_HPP
+#define BOOST_GEOMETRY_MULTI_IO_WKT_DETAIL_PREFIX_HPP
+
+#include <boost/geometry/multi/core/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt
+{
+
+struct prefix_null
+{
+ static inline const char* apply() { return ""; }
+};
+
+struct prefix_multipoint
+{
+ static inline const char* apply() { return "MULTIPOINT"; }
+};
+
+struct prefix_multilinestring
+{
+ static inline const char* apply() { return "MULTILINESTRING"; }
+};
+
+struct prefix_multipolygon
+{
+ static inline const char* apply() { return "MULTIPOLYGON"; }
+};
+
+}} // namespace wkt::impl
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_IO_WKT_DETAIL_PREFIX_HPP
diff --git a/src/boost/geometry/multi/io/wkt/read.hpp b/src/boost/geometry/multi/io/wkt/read.hpp
new file mode 100644
index 0000000..218ddf9
--- /dev/null
+++ b/src/boost/geometry/multi/io/wkt/read.hpp
@@ -0,0 +1,167 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_IO_WKT_READ_MULTI_HPP
+#define BOOST_GEOMETRY_MULTI_IO_WKT_READ_MULTI_HPP
+
+#include <string>
+
+#include <boost/geometry/core/mutable_range.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+#include <boost/geometry/multi/io/wkt/detail/prefix.hpp>
+#include <boost/geometry/io/wkt/read.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace wkt
+{
+
+template <typename MultiGeometry, template<typename> class Parser, typename PrefixPolicy>
+struct multi_parser
+{
+ static inline void apply(std::string const& wkt, MultiGeometry& geometry)
+ {
+ traits::clear<MultiGeometry>::apply(geometry);
+
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it;
+ if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ {
+ handle_open_parenthesis(it, tokens.end(), wkt);
+
+ // Parse sub-geometries
+ while(it != tokens.end() && *it != ")")
+ {
+ traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
+ Parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, geometry.back());
+ if (it != tokens.end() && *it == ",")
+ {
+ // Skip "," after multi-element is parsed
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, tokens.end(), wkt);
+ }
+
+ check_end(it, tokens.end(), wkt);
+ }
+};
+
+template <typename P>
+struct noparenthesis_point_parser
+{
+ static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+ std::string const& wkt, P& point)
+ {
+ parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+ }
+};
+
+template <typename MultiGeometry, typename PrefixPolicy>
+struct multi_point_parser
+{
+ static inline void apply(std::string const& wkt, MultiGeometry& geometry)
+ {
+ traits::clear<MultiGeometry>::apply(geometry);
+
+ tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+ tokenizer::iterator it;
+
+ if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+ {
+ handle_open_parenthesis(it, tokens.end(), wkt);
+
+ // If first point definition starts with "(" then parse points as (x y)
+ // otherwise as "x y"
+ bool using_brackets = (it != tokens.end() && *it == "(");
+
+ while(it != tokens.end() && *it != ")")
+ {
+ traits::resize<MultiGeometry>::apply(geometry, boost::size(geometry) + 1);
+
+ if (using_brackets)
+ {
+ point_parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, geometry.back());
+ }
+ else
+ {
+ noparenthesis_point_parser
+ <
+ typename boost::range_value<MultiGeometry>::type
+ >::apply(it, tokens.end(), wkt, geometry.back());
+ }
+
+ if (it != tokens.end() && *it == ",")
+ {
+ // Skip "," after point is parsed
+ ++it;
+ }
+ }
+
+ handle_close_parenthesis(it, tokens.end(), wkt);
+ }
+
+ check_end(it, tokens.end(), wkt);
+ }
+};
+
+}} // namespace detail::wkt
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiGeometry>
+struct read_wkt<multi_point_tag, MultiGeometry>
+ : detail::wkt::multi_point_parser
+ <
+ MultiGeometry,
+ detail::wkt::prefix_multipoint
+ >
+{};
+
+template <typename MultiGeometry>
+struct read_wkt<multi_linestring_tag, MultiGeometry>
+ : detail::wkt::multi_parser
+ <
+ MultiGeometry,
+ detail::wkt::linestring_parser,
+ detail::wkt::prefix_multilinestring
+ >
+{};
+
+template <typename MultiGeometry>
+struct read_wkt<multi_polygon_tag, MultiGeometry>
+ : detail::wkt::multi_parser
+ <
+ MultiGeometry,
+ detail::wkt::polygon_parser,
+ detail::wkt::prefix_multipolygon
+ >
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_IO_WKT_READ_MULTI_HPP
diff --git a/src/boost/geometry/multi/io/wkt/wkt.hpp b/src/boost/geometry/multi/io/wkt/wkt.hpp
new file mode 100644
index 0000000..55f1713
--- /dev/null
+++ b/src/boost/geometry/multi/io/wkt/wkt.hpp
@@ -0,0 +1,20 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_IO_WKT_WKT_HPP
+#define BOOST_GEOMETRY_MULTI_IO_WKT_WKT_HPP
+
+#include <boost/geometry/multi/io/wkt/read.hpp>
+#include <boost/geometry/multi/io/wkt/write.hpp>
+
+#endif // BOOST_GEOMETRY_MULTI_IO_WKT_WKT_HPP
diff --git a/src/boost/geometry/multi/io/wkt/write.hpp b/src/boost/geometry/multi/io/wkt/write.hpp
new file mode 100644
index 0000000..374da28
--- /dev/null
+++ b/src/boost/geometry/multi/io/wkt/write.hpp
@@ -0,0 +1,108 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_IO_WKT_WRITE_HPP
+#define BOOST_GEOMETRY_MULTI_IO_WKT_WRITE_HPP
+
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/io/wkt/detail/prefix.hpp>
+#include <boost/geometry/io/wkt/write.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt
+{
+
+template <typename Multi, typename StreamPolicy, typename PrefixPolicy>
+struct wkt_multi
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Multi const& geometry)
+ {
+ os << PrefixPolicy::apply();
+ // TODO: check EMPTY here
+ os << "(";
+
+ for (typename boost::range_iterator<Multi const>::type
+ it = boost::begin(geometry);
+ it != boost::end(geometry);
+ ++it)
+ {
+ if (it != boost::begin(geometry))
+ {
+ os << ",";
+ }
+ StreamPolicy::apply(os, *it);
+ }
+
+ os << ")";
+ }
+};
+
+}} // namespace wkt::impl
+#endif
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Multi>
+struct wkt<multi_point_tag, Multi>
+ : detail::wkt::wkt_multi
+ <
+ Multi,
+ detail::wkt::wkt_point
+ <
+ typename boost::range_value<Multi>::type,
+ detail::wkt::prefix_null
+ >,
+ detail::wkt::prefix_multipoint
+ >
+{};
+
+template <typename Multi>
+struct wkt<multi_linestring_tag, Multi>
+ : detail::wkt::wkt_multi
+ <
+ Multi,
+ detail::wkt::wkt_sequence
+ <
+ typename boost::range_value<Multi>::type
+ >,
+ detail::wkt::prefix_multilinestring
+ >
+{};
+
+template <typename Multi>
+struct wkt<multi_polygon_tag, Multi>
+ : detail::wkt::wkt_multi
+ <
+ Multi,
+ detail::wkt::wkt_poly
+ <
+ typename boost::range_value<Multi>::type,
+ detail::wkt::prefix_null
+ >,
+ detail::wkt::prefix_multipolygon
+ >
+{};
+
+} // namespace dispatch
+#endif
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_IO_WKT_WRITE_HPP
diff --git a/src/boost/geometry/multi/multi.hpp b/src/boost/geometry/multi/multi.hpp
new file mode 100644
index 0000000..db33a9d
--- /dev/null
+++ b/src/boost/geometry/multi/multi.hpp
@@ -0,0 +1,77 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_HPP
+#define BOOST_GEOMETRY_MULTI_HPP
+
+
+#include <boost/geometry/multi/core/closure.hpp>
+#include <boost/geometry/multi/core/geometry_id.hpp>
+#include <boost/geometry/multi/core/interior_rings.hpp>
+#include <boost/geometry/multi/core/is_areal.hpp>
+#include <boost/geometry/multi/core/point_order.hpp>
+#include <boost/geometry/multi/core/point_type.hpp>
+#include <boost/geometry/multi/core/ring_type.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/core/topological_dimension.hpp>
+
+#include <boost/geometry/multi/algorithms/append.hpp>
+#include <boost/geometry/multi/algorithms/area.hpp>
+#include <boost/geometry/multi/algorithms/centroid.hpp>
+#include <boost/geometry/multi/algorithms/clear.hpp>
+#include <boost/geometry/multi/algorithms/convert.hpp>
+#include <boost/geometry/multi/algorithms/correct.hpp>
+#include <boost/geometry/multi/algorithms/covered_by.hpp>
+#include <boost/geometry/multi/algorithms/distance.hpp>
+#include <boost/geometry/multi/algorithms/envelope.hpp>
+#include <boost/geometry/multi/algorithms/equals.hpp>
+#include <boost/geometry/multi/algorithms/for_each.hpp>
+#include <boost/geometry/multi/algorithms/intersection.hpp>
+#include <boost/geometry/multi/algorithms/length.hpp>
+#include <boost/geometry/multi/algorithms/num_geometries.hpp>
+#include <boost/geometry/multi/algorithms/num_interior_rings.hpp>
+#include <boost/geometry/multi/algorithms/num_points.hpp>
+#include <boost/geometry/multi/algorithms/perimeter.hpp>
+#include <boost/geometry/multi/algorithms/reverse.hpp>
+#include <boost/geometry/multi/algorithms/simplify.hpp>
+#include <boost/geometry/multi/algorithms/transform.hpp>
+#include <boost/geometry/multi/algorithms/unique.hpp>
+#include <boost/geometry/multi/algorithms/within.hpp>
+
+#include <boost/geometry/multi/algorithms/detail/for_each_range.hpp>
+#include <boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp>
+#include <boost/geometry/multi/algorithms/detail/multi_sum.hpp>
+
+#include <boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp>
+#include <boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp>
+
+#include <boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/get_ring.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/select_rings.hpp>
+#include <boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp>
+
+#include <boost/geometry/multi/geometries/concepts/check.hpp>
+#include <boost/geometry/multi/geometries/concepts/multi_point_concept.hpp>
+#include <boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp>
+#include <boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp>
+
+#include <boost/geometry/multi/views/detail/range_type.hpp>
+#include <boost/geometry/multi/strategies/cartesian/centroid_average.hpp>
+
+#include <boost/geometry/multi/io/dsv/write.hpp>
+#include <boost/geometry/multi/io/wkt/wkt.hpp>
+
+
+#endif // BOOST_GEOMETRY_MULTI_HPP
diff --git a/src/boost/geometry/multi/strategies/cartesian/centroid_average.hpp b/src/boost/geometry/multi/strategies/cartesian/centroid_average.hpp
new file mode 100644
index 0000000..f28daf2
--- /dev/null
+++ b/src/boost/geometry/multi/strategies/cartesian/centroid_average.hpp
@@ -0,0 +1,116 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
+#define BOOST_GEOMETRY_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
+
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/strategies/centroid.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace centroid
+{
+
+
+/*!
+\brief Centroid calculation taking average of points
+\ingroup strategies
+*/
+template
+<
+ typename PointCentroid,
+ typename Point = PointCentroid
+>
+class average
+{
+private :
+
+ /*! subclass to keep state */
+ class sum
+ {
+ friend class average;
+ int count;
+ PointCentroid centroid;
+
+ public :
+ inline sum()
+ : count(0)
+ {
+ assign_zero(centroid);
+ }
+ };
+
+public :
+ typedef sum state_type;
+ typedef PointCentroid centroid_point_type;
+ typedef Point point_type;
+
+ static inline void apply(Point const& p, sum& state)
+ {
+ add_point(state.centroid, p);
+ state.count++;
+ }
+
+ static inline void result(sum const& state, PointCentroid& centroid)
+ {
+ centroid = state.centroid;
+ divide_value(centroid, state.count);
+ }
+
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace services
+{
+
+template <typename Point, std::size_t DimensionCount, typename Geometry>
+struct default_strategy
+<
+ cartesian_tag,
+ pointlike_tag,
+ DimensionCount,
+ Point,
+ Geometry
+>
+{
+ typedef average
+ <
+ Point,
+ typename point_type<Geometry>::type
+ > type;
+};
+
+} // namespace services
+
+#endif
+
+
+}} // namespace strategy::centroid
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
diff --git a/src/boost/geometry/multi/util/write_dsv.hpp b/src/boost/geometry/multi/util/write_dsv.hpp
new file mode 100644
index 0000000..2ab97df
--- /dev/null
+++ b/src/boost/geometry/multi/util/write_dsv.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_UTIL_WRITE_DSV_HPP
+#define BOOST_GEOMETRY_MULTI_UTIL_WRITE_DSV_HPP
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/io/dsv/write.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv
+{
+
+
+template <typename MultiGeometry>
+struct dsv_multi
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ MultiGeometry const& multi,
+ dsv_settings const& settings)
+ {
+ os << settings.list_open;
+
+ typedef typename boost::range_iterator
+ <
+ MultiGeometry const
+ >::type iterator;
+ for(iterator it = boost::begin(multi);
+ it != boost::end(multi);
+ ++it)
+ {
+ os << geometry::dsv(*it);
+ }
+ os << settings.list_close;
+ }
+};
+
+
+
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry>
+struct dsv<multi_tag, Geometry>
+ : detail::dsv::dsv_multi<Geometry>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_UTIL_WRITE_DSV_HPP
diff --git a/src/boost/geometry/multi/views/detail/range_type.hpp b/src/boost/geometry/multi/views/detail/range_type.hpp
new file mode 100644
index 0000000..172feb2
--- /dev/null
+++ b/src/boost/geometry/multi/views/detail/range_type.hpp
@@ -0,0 +1,62 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_VIEWS_DETAIL_RANGE_TYPE_HPP
+#define BOOST_GEOMETRY_MULTI_VIEWS_DETAIL_RANGE_TYPE_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/views/detail/range_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// multi-point acts itself as a range
+template <typename Geometry>
+struct range_type<multi_point_tag, Geometry>
+{
+ typedef Geometry type;
+};
+
+
+template <typename Geometry>
+struct range_type<multi_linestring_tag, Geometry>
+{
+ typedef typename boost::range_value<Geometry>::type type;
+};
+
+
+template <typename Geometry>
+struct range_type<multi_polygon_tag, Geometry>
+{
+ // Call its single-version
+ typedef typename geometry::detail::range_type
+ <
+ typename boost::range_value<Geometry>::type
+ >::type type;
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_MULTI_VIEWS_DETAIL_RANGE_TYPE_HPP
diff --git a/src/boost/geometry/policies/compare.hpp b/src/boost/geometry/policies/compare.hpp
new file mode 100644
index 0000000..2e952d3
--- /dev/null
+++ b/src/boost/geometry/policies/compare.hpp
@@ -0,0 +1,242 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_POLICIES_COMPARE_HPP
+#define BOOST_GEOMETRY_POLICIES_COMPARE_HPP
+
+
+#include <cstddef>
+
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace compare
+{
+
+
+template
+<
+ int Direction,
+ typename Point,
+ typename Strategy,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct compare_loop
+{
+ typedef typename strategy::compare::detail::select_strategy
+ <
+ Strategy, Direction, Point, Dimension
+ >::type compare_type;
+
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+
+ static inline bool apply(Point const& left, Point const& right)
+ {
+ coordinate_type const& cleft = geometry::get<Dimension>(left);
+ coordinate_type const& cright = geometry::get<Dimension>(right);
+
+ if (geometry::math::equals(cleft, cright))
+ {
+ return compare_loop
+ <
+ Direction, Point, Strategy,
+ Dimension + 1, DimensionCount
+ >::apply(left, right);
+ }
+ else
+ {
+ compare_type compare;
+ return compare(cleft, cright);
+ }
+ }
+};
+
+template
+<
+ int Direction,
+ typename Point,
+ typename Strategy,
+ std::size_t DimensionCount
+>
+struct compare_loop<Direction, Point, Strategy, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Point const&, Point const&)
+ {
+ // On coming here, points are equal. Return true if
+ // direction = 0 (equal), false if -1/1 (greater/less)
+ return Direction == 0;
+ }
+};
+
+
+template <int Direction, typename Point, typename Strategy>
+struct compare_in_all_dimensions
+{
+ inline bool operator()(Point const& left, Point const& right) const
+ {
+ return detail::compare::compare_loop
+ <
+ Direction, Point, Strategy,
+ 0, geometry::dimension<Point>::type::value
+ >::apply(left, right);
+ }
+};
+
+
+template <typename Point, typename Strategy, std::size_t Dimension>
+class compare_in_one_dimension
+{
+ Strategy compare;
+
+public :
+ inline bool operator()(Point const& left, Point const& right) const
+ {
+ typedef typename geometry::coordinate_type<Point>::type coordinate_type;
+
+ coordinate_type const& cleft = get<Dimension>(left);
+ coordinate_type const& cright = get<Dimension>(right);
+ return compare(cleft, cright);
+ }
+};
+
+}} // namespace detail::compare
+
+#endif
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ int Direction,
+ typename Point,
+ typename Strategy,
+ int Dimension
+>
+struct compare_geometries
+ : detail::compare::compare_in_one_dimension
+ <
+ Point,
+ typename strategy::compare::detail::select_strategy
+ <
+ Strategy, Direction, Point, Dimension
+ >::type,
+ Dimension
+ >
+{};
+
+
+// Specialization with -1: compare in all dimensions
+template <int Direction, typename Point, typename Strategy>
+struct compare_geometries<Direction, Point, Strategy, -1>
+ : detail::compare::compare_in_all_dimensions<Direction, Point, Strategy>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Less functor, to sort points in ascending order.
+\ingroup compare
+\details This functor compares points and orders them on x,
+ then on y, then on z coordinate.
+\tparam Geometry the geometry
+\tparam Dimension the dimension to sort on, defaults to -1,
+ indicating ALL dimensions. That's to say, first on x,
+ on equal x-es then on y, etc.
+ If a dimension is specified, only that dimension is considered
+\tparam Strategy underlying coordinate comparing functor,
+ defaults to the default comparison strategies
+ related to the point coordinate system. If specified, the specified
+ strategy is used. This can e.g. be std::less<double>.
+*/
+template
+<
+ typename Point,
+ int Dimension = -1,
+ typename Strategy = strategy::compare::default_strategy
+>
+struct less
+ : dispatch::compare_geometries
+ <
+ 1, // indicates ascending
+ Point,
+ Strategy,
+ Dimension
+ >
+{
+ typedef Point first_argument_type;
+ typedef Point second_argument_type;
+ typedef bool result_type;
+};
+
+
+/*!
+\brief Greater functor
+\ingroup compare
+\details Can be used to sort points in reverse order
+\see Less functor
+*/
+template
+<
+ typename Point,
+ int Dimension = -1,
+ typename Strategy = strategy::compare::default_strategy
+>
+struct greater
+ : dispatch::compare_geometries
+ <
+ -1, // indicates descending
+ Point,
+ Strategy,
+ Dimension
+ >
+{};
+
+
+/*!
+\brief Equal To functor, to compare if points are equal
+\ingroup compare
+\tparam Geometry the geometry
+\tparam Dimension the dimension to compare on, defaults to -1,
+ indicating ALL dimensions.
+ If a dimension is specified, only that dimension is considered
+\tparam Strategy underlying coordinate comparing functor
+*/
+template
+<
+ typename Point,
+ int Dimension = -1,
+ typename Strategy = strategy::compare::default_strategy
+>
+struct equal_to
+ : dispatch::compare_geometries
+ <
+ 0,
+ Point,
+ Strategy,
+ Dimension
+ >
+{};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_POLICIES_COMPARE_HPP
diff --git a/src/boost/geometry/policies/relate/de9im.hpp b/src/boost/geometry/policies/relate/de9im.hpp
new file mode 100644
index 0000000..766d80b
--- /dev/null
+++ b/src/boost/geometry/policies/relate/de9im.hpp
@@ -0,0 +1,177 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
+#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
+
+
+#include <boost/geometry/strategies/intersection_result.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace policies { namespace relate
+{
+
+
+template <typename S1, typename S2>
+struct segments_de9im
+{
+ typedef de9im_segment return_type;
+ typedef S1 segment_type1;
+ typedef S2 segment_type2;
+ typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
+
+ static inline return_type rays_intersect(bool on_segment,
+ double ra, double rb,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ coordinate_type const& dx2, coordinate_type const& dy2,
+ coordinate_type const& wx, coordinate_type const& wy,
+ S1 const& s1, S2 const& s2)
+ {
+ if(on_segment)
+ {
+ // 0 <= ra <= 1 and 0 <= rb <= 1
+ // Now check if one of them is 0 or 1, these are "touch" cases
+ bool a = math::equals(ra, 0.0) || math::equals(ra, 1.0);
+ bool b = math::equals(rb, 0.0) || math::equals(rb, 1.0);
+ if (a && b)
+ {
+ // Touch boundary/boundary: i-i == -1, i-b == -1, b-b == 0
+ // Opposite: if both are equal they touch in opposite direction
+ return de9im_segment(ra,rb,
+ -1, -1, 1,
+ -1, 0, 0,
+ 1, 0, 2, false, math::equals(ra,rb));
+ }
+ else if (a || b)
+ {
+ // Touch boundary/interior: i-i == -1, i-b == -1 or 0, b-b == -1
+ int A = a ? 0 : -1;
+ int B = b ? 0 : -1;
+ return de9im_segment(ra,rb,
+ -1, B, 1,
+ A, -1, 0,
+ 1, 0, 2);
+ }
+
+ // Intersects: i-i == 0, i-b == -1, i-e == 1
+ return de9im_segment(ra,rb,
+ 0, -1, 1,
+ -1, -1, 0,
+ 1, 0, 2);
+ }
+
+ // Not on segment, disjoint
+ return de9im_segment(ra,rb,
+ -1, -1, 1,
+ -1, -1, 0,
+ 1, 0, 2);
+ }
+
+ static inline return_type collinear_touch(coordinate_type const& x,
+ coordinate_type const& y, bool opposite, char)
+ {
+ return de9im_segment(0,0,
+ -1, -1, 1,
+ -1, 0, 0,
+ 1, 0, 2,
+ true, opposite);
+ }
+
+ template <typename S>
+ static inline return_type collinear_interior_boundary_intersect(S const& s,
+ bool a_within_b, bool opposite)
+ {
+ return a_within_b
+ ? de9im_segment(0,0,
+ 1, -1, -1,
+ 0, 0, -1,
+ 1, 0, 2,
+ true, opposite)
+ : de9im_segment(0,0,
+ 1, 0, 1,
+ -1, 0, 0,
+ -1, -1, 2,
+ true, opposite);
+ }
+
+
+
+ static inline return_type collinear_a_in_b(S1 const& s, bool opposite)
+ {
+ return de9im_segment(0,0,
+ 1, -1, -1,
+ 0, -1, -1,
+ 1, 0, 2,
+ true, opposite);
+ }
+ static inline return_type collinear_b_in_a(S2 const& s, bool opposite)
+ {
+ return de9im_segment(0,0,
+ 1, 0, 1,
+ -1, -1, 0,
+ -1, -1, 2,
+ true, opposite);
+ }
+
+ static inline return_type collinear_overlaps(
+ coordinate_type const& x1, coordinate_type const& y1,
+ coordinate_type const& x2, coordinate_type const& y2, bool opposite)
+ {
+ return de9im_segment(0,0,
+ 1, 0, 1,
+ 0, -1, 0,
+ 1, 0, 2,
+ true, opposite);
+ }
+
+ static inline return_type segment_equal(S1 const& s, bool opposite)
+ {
+ return de9im_segment(0,0,
+ 1, -1, -1,
+ -1, 0, -1,
+ -1, -1, 2,
+ true, opposite);
+ }
+
+ static inline return_type degenerate(S1 const& segment, bool a_degenerate)
+ {
+ return a_degenerate
+ ? de9im_segment(0,0,
+ 0, -1, -1,
+ -1, -1, -1,
+ 1, 0, 2,
+ false, false, false, true)
+ : de9im_segment(0,0,
+ 0, -1, 1,
+ -1, -1, 0,
+ -1, -1, 2,
+ false, false, false, true);
+ }
+
+ static inline return_type collinear_disjoint()
+ {
+ return de9im_segment(0,0,
+ -1, -1, 1,
+ -1, -1, 0,
+ 1, 0, 2,
+ true);
+ }
+
+};
+
+
+}} // namespace policies::relate
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
diff --git a/src/boost/geometry/policies/relate/direction.hpp b/src/boost/geometry/policies/relate/direction.hpp
new file mode 100644
index 0000000..cfbaf7d
--- /dev/null
+++ b/src/boost/geometry/policies/relate/direction.hpp
@@ -0,0 +1,362 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
+#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
+
+
+#include <cstddef>
+#include <string>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/arithmetic/determinant.hpp>
+#include <boost/geometry/strategies/side_info.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace policies { namespace relate
+{
+
+struct direction_type
+{
+ // NOTE: "char" will be replaced by enum in future version
+
+ inline direction_type(side_info const& s, char h,
+ int ha, int hb,
+ int da = 0, int db = 0,
+ bool op = false)
+ : how(h)
+ , opposite(op)
+ , how_a(ha)
+ , how_b(hb)
+ , dir_a(da)
+ , dir_b(db)
+ , sides(s)
+ {
+ arrival[0] = ha;
+ arrival[1] = hb;
+ }
+
+ inline direction_type(char h, bool op, int ha = 0, int hb = 0)
+ : how(h)
+ , opposite(op)
+ , how_a(ha)
+ , how_b(hb)
+ , dir_a(0)
+ , dir_b(0)
+ {
+ arrival[0] = ha;
+ arrival[1] = hb;
+ }
+
+
+ // TODO: replace this
+ // NOTE: "char" will be replaced by enum in future version
+ // "How" is the intersection formed?
+ char how;
+
+ // Is it opposite (for collinear/equal cases)
+ bool opposite;
+
+ // Information on how A arrives at intersection, how B arrives at intersection
+ // 1: arrives at intersection
+ // -1: starts from intersection
+ int how_a;
+ int how_b;
+
+ // Direction: how is A positioned from B
+ // 1: points left, seen from IP
+ // -1: points right, seen from IP
+ // In case of intersection: B's TO direction
+ // In case that B's TO direction is at A: B's from direction
+ // In collinear cases: it is 0
+ int dir_a; // Direction of A-s TO from IP
+ int dir_b; // Direction of B-s TO from IP
+
+ // New information
+ side_info sides;
+ int arrival[2]; // 1=arrival, -1departure, 0=neutral; == how_a//how_b
+
+
+ // About arrival[0] (== arrival of a2 w.r.t. b) for COLLINEAR cases
+ // Arrival 1: a1--------->a2 (a arrives within b)
+ // b1----->b2
+
+ // Arrival 1: (a in b)
+ //
+
+
+ // Arrival -1: a1--------->a2 (a does not arrive within b)
+ // b1----->b2
+
+ // Arrival -1: (b in a) a_1-------------a_2
+ // b_1---b_2
+
+ // Arrival 0: a1------->a2 (a arrives at TO-border of b)
+ // b1--->b2
+
+};
+
+
+template <typename S1, typename S2, typename CalculationType = void>
+struct segments_direction
+{
+ typedef direction_type return_type;
+ typedef S1 segment_type1;
+ typedef S2 segment_type2;
+ typedef typename select_calculation_type
+ <
+ S1, S2, CalculationType
+ >::type coordinate_type;
+
+ // Get the same type, but at least a double
+ typedef typename select_most_precise<coordinate_type, double>::type rtype;
+
+
+ template <typename R>
+ static inline return_type segments_intersect(side_info const& sides,
+ R const&,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ coordinate_type const& dx2, coordinate_type const& dy2,
+ S1 const& s1, S2 const& s2)
+ {
+ bool const ra0 = sides.get<0,0>() == 0;
+ bool const ra1 = sides.get<0,1>() == 0;
+ bool const rb0 = sides.get<1,0>() == 0;
+ bool const rb1 = sides.get<1,1>() == 0;
+
+ return
+ // opposite and same starting point (FROM)
+ ra0 && rb0 ? calculate_side<1>(sides, dx1, dy1, s1, s2, 'f', -1, -1)
+
+ // opposite and point to each other (TO)
+ : ra1 && rb1 ? calculate_side<0>(sides, dx1, dy1, s1, s2, 't', 1, 1)
+
+ // not opposite, forming an angle, first a then b,
+ // directed either both left, or both right
+ // Check side of B2 from A. This is not calculated before
+ : ra1 && rb0 ? angle<1>(sides, dx1, dy1, s1, s2, 'a', 1, -1)
+
+ // not opposite, forming a angle, first b then a,
+ // directed either both left, or both right
+ : ra0 && rb1 ? angle<0>(sides, dx1, dy1, s1, s2, 'a', -1, 1)
+
+ // b starts from interior of a
+ : rb0 ? starts_from_middle(sides, dx1, dy1, s1, s2, 'B', 0, -1)
+
+ // a starts from interior of b (#39)
+ : ra0 ? starts_from_middle(sides, dx1, dy1, s1, s2, 'A', -1, 0)
+
+ // b ends at interior of a, calculate direction of A from IP
+ : rb1 ? b_ends_at_middle(sides, dx2, dy2, s1, s2)
+
+ // a ends at interior of b
+ : ra1 ? a_ends_at_middle(sides, dx1, dy1, s1, s2)
+
+ // normal intersection
+ : calculate_side<1>(sides, dx1, dy1, s1, s2, 'i', -1, -1)
+ ;
+ }
+
+ static inline return_type collinear_touch(
+ coordinate_type const& ,
+ coordinate_type const& , int arrival_a, int arrival_b)
+ {
+ // Though this is 'collinear', we handle it as To/From/Angle because it is the same.
+ // It only does NOT have a direction.
+ side_info sides;
+ //int const arrive = how == 'T' ? 1 : -1;
+ bool opposite = arrival_a == arrival_b;
+ return
+ ! opposite
+ ? return_type(sides, 'a', arrival_a, arrival_b)
+ : return_type(sides, arrival_a == 0 ? 't' : 'f', arrival_a, arrival_b, 0, 0, true);
+ }
+
+ template <typename S>
+ static inline return_type collinear_interior_boundary_intersect(S const& , bool,
+ int arrival_a, int arrival_b, bool opposite)
+ {
+ return_type r('c', opposite);
+ r.arrival[0] = arrival_a;
+ r.arrival[1] = arrival_b;
+ return r;
+ }
+
+ static inline return_type collinear_a_in_b(S1 const& , bool opposite)
+ {
+ return_type r('c', opposite);
+ r.arrival[0] = 1;
+ r.arrival[1] = -1;
+ return r;
+ }
+ static inline return_type collinear_b_in_a(S2 const& , bool opposite)
+ {
+ return_type r('c', opposite);
+ r.arrival[0] = -1;
+ r.arrival[1] = 1;
+ return r;
+ }
+
+ static inline return_type collinear_overlaps(
+ coordinate_type const& , coordinate_type const& ,
+ coordinate_type const& , coordinate_type const& ,
+ int arrival_a, int arrival_b, bool opposite)
+ {
+ return_type r('c', opposite);
+ r.arrival[0] = arrival_a;
+ r.arrival[1] = arrival_b;
+ return r;
+ }
+
+ static inline return_type segment_equal(S1 const& , bool opposite)
+ {
+ return return_type('e', opposite);
+ }
+
+ static inline return_type degenerate(S1 const& , bool)
+ {
+ return return_type('0', false);
+ }
+
+ static inline return_type disjoint()
+ {
+ return return_type('d', false);
+ }
+
+ static inline return_type collinear_disjoint()
+ {
+ return return_type('d', false);
+ }
+
+ static inline return_type error(std::string const&)
+ {
+ // Return "E" to denote error
+ // This will throw an error in get_turn_info
+ // TODO: change to enum or similar
+ return return_type('E', false);
+ }
+
+private :
+
+ static inline bool is_left
+ (
+ coordinate_type const& ux,
+ coordinate_type const& uy,
+ coordinate_type const& vx,
+ coordinate_type const& vy
+ )
+ {
+ // This is a "side calculation" as in the strategies, but here terms are precalculated
+ // We might merge this with side, offering a pre-calculated term (in fact already done using cross-product)
+ // Waiting for implementing spherical...
+
+ rtype const zero = rtype();
+ return geometry::detail::determinant<rtype>(ux, uy, vx, vy) > zero;
+ }
+
+ template <std::size_t I>
+ static inline return_type calculate_side(side_info const& sides,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ S1 const& s1, S2 const& s2,
+ char how, int how_a, int how_b)
+ {
+ coordinate_type dpx = get<I, 0>(s2) - get<0, 0>(s1);
+ coordinate_type dpy = get<I, 1>(s2) - get<0, 1>(s1);
+
+ return is_left(dx1, dy1, dpx, dpy)
+ ? return_type(sides, how, how_a, how_b, -1, 1)
+ : return_type(sides, how, how_a, how_b, 1, -1);
+ }
+
+ template <std::size_t I>
+ static inline return_type angle(side_info const& sides,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ S1 const& s1, S2 const& s2,
+ char how, int how_a, int how_b)
+ {
+ coordinate_type dpx = get<I, 0>(s2) - get<0, 0>(s1);
+ coordinate_type dpy = get<I, 1>(s2) - get<0, 1>(s1);
+
+ return is_left(dx1, dy1, dpx, dpy)
+ ? return_type(sides, how, how_a, how_b, 1, 1)
+ : return_type(sides, how, how_a, how_b, -1, -1);
+ }
+
+
+ static inline return_type starts_from_middle(side_info const& sides,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ S1 const& s1, S2 const& s2,
+ char which,
+ int how_a, int how_b)
+ {
+ // Calculate ARROW of b segment w.r.t. s1
+ coordinate_type dpx = get<1, 0>(s2) - get<0, 0>(s1);
+ coordinate_type dpy = get<1, 1>(s2) - get<0, 1>(s1);
+
+ int dir = is_left(dx1, dy1, dpx, dpy) ? 1 : -1;
+
+ // From other perspective, then reverse
+ bool const is_a = which == 'A';
+ if (is_a)
+ {
+ dir = -dir;
+ }
+
+ return return_type(sides, 's',
+ how_a,
+ how_b,
+ is_a ? dir : -dir,
+ ! is_a ? dir : -dir);
+ }
+
+
+
+ // To be harmonized
+ static inline return_type a_ends_at_middle(side_info const& sides,
+ coordinate_type const& dx, coordinate_type const& dy,
+ S1 const& s1, S2 const& s2)
+ {
+ coordinate_type dpx = get<1, 0>(s2) - get<0, 0>(s1);
+ coordinate_type dpy = get<1, 1>(s2) - get<0, 1>(s1);
+
+ // Ending at the middle, one ARRIVES, the other one is NEUTRAL
+ // (because it both "arrives" and "departs" there
+ return is_left(dx, dy, dpx, dpy)
+ ? return_type(sides, 'm', 1, 0, 1, 1)
+ : return_type(sides, 'm', 1, 0, -1, -1);
+ }
+
+
+ static inline return_type b_ends_at_middle(side_info const& sides,
+ coordinate_type const& dx, coordinate_type const& dy,
+ S1 const& s1, S2 const& s2)
+ {
+ coordinate_type dpx = get<1, 0>(s1) - get<0, 0>(s2);
+ coordinate_type dpy = get<1, 1>(s1) - get<0, 1>(s2);
+
+ return is_left(dx, dy, dpx, dpy)
+ ? return_type(sides, 'm', 0, 1, 1, 1)
+ : return_type(sides, 'm', 0, 1, -1, -1);
+ }
+
+};
+
+}} // namespace policies::relate
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
diff --git a/src/boost/geometry/policies/relate/intersection_points.hpp b/src/boost/geometry/policies/relate/intersection_points.hpp
new file mode 100644
index 0000000..d7d5199
--- /dev/null
+++ b/src/boost/geometry/policies/relate/intersection_points.hpp
@@ -0,0 +1,165 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+
+
+#include <algorithm>
+#include <string>
+
+#include <boost/concept_check.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/arithmetic/determinant.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/strategies/side_info.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace policies { namespace relate
+{
+
+
+template <typename S1, typename S2, typename ReturnType, typename CalculationType = void>
+struct segments_intersection_points
+{
+ typedef ReturnType return_type;
+ typedef S1 segment_type1;
+ typedef S2 segment_type2;
+
+ typedef typename select_calculation_type
+ <
+ S1, S2, CalculationType
+ >::type coordinate_type;
+
+ template <typename R>
+ static inline return_type segments_intersect(side_info const&,
+ R const& r,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ coordinate_type const& dx2, coordinate_type const& dy2,
+ S1 const& s1, S2 const& s2)
+ {
+ typedef typename geometry::coordinate_type
+ <
+ typename return_type::point_type
+ >::type return_coordinate_type;
+
+ coordinate_type const s1x = get<0, 0>(s1);
+ coordinate_type const s1y = get<0, 1>(s1);
+
+ return_type result;
+ result.count = 1;
+ set<0>(result.intersections[0],
+ boost::numeric_cast<return_coordinate_type>(R(s1x) + r * R(dx1)));
+ set<1>(result.intersections[0],
+ boost::numeric_cast<return_coordinate_type>(R(s1y) + r * R(dy1)));
+
+ return result;
+ }
+
+ static inline return_type collinear_touch(coordinate_type const& x,
+ coordinate_type const& y, int, int)
+ {
+ return_type result;
+ result.count = 1;
+ set<0>(result.intersections[0], x);
+ set<1>(result.intersections[0], y);
+ return result;
+ }
+
+ template <typename S>
+ static inline return_type collinear_inside(S const& s, int index1 = 0, int index2 = 1)
+ {
+ return_type result;
+ result.count = 2;
+ set<0>(result.intersections[index1], get<0, 0>(s));
+ set<1>(result.intersections[index1], get<0, 1>(s));
+ set<0>(result.intersections[index2], get<1, 0>(s));
+ set<1>(result.intersections[index2], get<1, 1>(s));
+ return result;
+ }
+
+ template <typename S>
+ static inline return_type collinear_interior_boundary_intersect(S const& s, bool a_in_b,
+ int, int, bool opposite)
+ {
+ int index1 = opposite && ! a_in_b ? 1 : 0;
+ return collinear_inside(s, index1, 1 - index1);
+ }
+
+ static inline return_type collinear_a_in_b(S1 const& s, bool)
+ {
+ return collinear_inside(s);
+ }
+ static inline return_type collinear_b_in_a(S2 const& s, bool opposite)
+ {
+ int index1 = opposite ? 1 : 0;
+ return collinear_inside(s, index1, 1 - index1);
+ }
+
+ static inline return_type collinear_overlaps(
+ coordinate_type const& x1, coordinate_type const& y1,
+ coordinate_type const& x2, coordinate_type const& y2,
+ int, int, bool)
+ {
+ return_type result;
+ result.count = 2;
+ set<0>(result.intersections[0], x1);
+ set<1>(result.intersections[0], y1);
+ set<0>(result.intersections[1], x2);
+ set<1>(result.intersections[1], y2);
+ return result;
+ }
+
+ static inline return_type segment_equal(S1 const& s, bool)
+ {
+ return_type result;
+ result.count = 2;
+ // TODO: order of IP's
+ set<0>(result.intersections[0], get<0, 0>(s));
+ set<1>(result.intersections[0], get<0, 1>(s));
+ set<0>(result.intersections[1], get<1, 0>(s));
+ set<1>(result.intersections[1], get<1, 1>(s));
+ return result;
+ }
+
+ static inline return_type disjoint()
+ {
+ return return_type();
+ }
+ static inline return_type error(std::string const&)
+ {
+ return return_type();
+ }
+
+ static inline return_type collinear_disjoint()
+ {
+ return return_type();
+ }
+
+ static inline return_type degenerate(S1 const& s, bool)
+ {
+ return_type result;
+ result.count = 1;
+ set<0>(result.intersections[0], get<0, 0>(s));
+ set<1>(result.intersections[0], get<0, 1>(s));
+ return result;
+ }
+};
+
+
+}} // namespace policies::relate
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
diff --git a/src/boost/geometry/policies/relate/intersection_points_determinant.hpp b/src/boost/geometry/policies/relate/intersection_points_determinant.hpp
new file mode 100644
index 0000000..bf43ef5
--- /dev/null
+++ b/src/boost/geometry/policies/relate/intersection_points_determinant.hpp
@@ -0,0 +1,176 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+
+
+#include <string>
+
+#include <boost/concept_check.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/strategies/side_info.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace policies { namespace relate
+{
+
+
+template <typename S1, typename S2, typename ReturnType, typename CalculationType = void>
+struct segments_intersection_points
+{
+ typedef ReturnType return_type;
+ typedef S1 segment_type1;
+ typedef S2 segment_type2;
+ typedef typename select_calculation_type
+ <
+ S1, S2, CalculationType
+ >::type coordinate_type;
+
+ // Get the same type, but at least a double
+ typedef typename select_most_precise<coordinate_type, double>::type rtype;
+
+ static inline return_type segments_intersect(side_info const&,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ coordinate_type const& dx2, coordinate_type const& dy2,
+ S1 const& s1, S2 const& s2)
+ {
+ return_type result;
+ typedef typename geometry::coordinate_type
+ <
+ typename return_type::point_type
+ >::type coordinate_type;
+
+ // Get the same type, but at least a double (also used for divisions
+ typedef typename select_most_precise
+ <
+ coordinate_type, double
+ >::type promoted_type;
+
+ coordinate_type const s1x = get<0, 0>(s1);
+ coordinate_type const s1y = get<0, 1>(s1);
+
+ // Calculate other determinants - Cramers rule
+ promoted_type const wx = get<0, 0>(s1) - get<0, 0>(s2);
+ promoted_type const wy = get<0, 1>(s1) - get<0, 1>(s2);
+ promoted_type const d = (dy2 * dx1) - (dx2 * dy1);
+ promoted_type const da = (dx2 * wy) - (dy2 * wx);
+
+ // r: ratio 0-1 where intersection divides A/B
+ promoted_type const r = da / d;
+
+ result.count = 1;
+ set<0>(result.intersections[0],
+ boost::numeric_cast<coordinate_type>(s1x + r * dx1));
+ set<1>(result.intersections[0],
+ boost::numeric_cast<coordinate_type>(s1y + r * dy1));
+
+ return result;
+ }
+
+ static inline return_type collinear_touch(coordinate_type const& x,
+ coordinate_type const& y, bool, char)
+ {
+ return_type result;
+ result.count = 1;
+ set<0>(result.intersections[0], x);
+ set<1>(result.intersections[0], y);
+ return result;
+ }
+
+ template <typename S>
+ static inline return_type collinear_inside(S const& s)
+ {
+ return_type result;
+ result.count = 2;
+ set<0>(result.intersections[0], get<0, 0>(s));
+ set<1>(result.intersections[0], get<0, 1>(s));
+ set<0>(result.intersections[1], get<1, 0>(s));
+ set<1>(result.intersections[1], get<1, 1>(s));
+ return result;
+ }
+
+ template <typename S>
+ static inline return_type collinear_interior_boundary_intersect(S const& s, bool, bool)
+ {
+ return collinear_inside(s);
+ }
+
+ static inline return_type collinear_a_in_b(S1 const& s, bool)
+ {
+ return collinear_inside(s);
+ }
+ static inline return_type collinear_b_in_a(S2 const& s, bool)
+ {
+ return collinear_inside(s);
+ }
+
+ static inline return_type collinear_overlaps(
+ coordinate_type const& x1, coordinate_type const& y1,
+ coordinate_type const& x2, coordinate_type const& y2, bool)
+ {
+ return_type result;
+ result.count = 2;
+ set<0>(result.intersections[0], x1);
+ set<1>(result.intersections[0], y1);
+ set<0>(result.intersections[1], x2);
+ set<1>(result.intersections[1], y2);
+ return result;
+ }
+
+ static inline return_type segment_equal(S1 const& s, bool)
+ {
+ return_type result;
+ result.count = 2;
+ set<0>(result.intersections[0], get<0, 0>(s));
+ set<1>(result.intersections[0], get<0, 1>(s));
+ set<0>(result.intersections[1], get<1, 0>(s));
+ set<1>(result.intersections[1], get<1, 1>(s));
+ return result;
+ }
+
+ static inline return_type disjoint()
+ {
+ return return_type();
+ }
+ static inline return_type error(std::string const& msg)
+ {
+ return return_type();
+ }
+
+ static inline return_type collinear_disjoint()
+ {
+ return return_type();
+ }
+ static inline return_type parallel()
+ {
+ return return_type();
+ }
+ static inline return_type degenerate(S1 const& s, bool)
+ {
+ return_type result;
+ result.count = 1;
+ set<0>(result.intersections[0], get<0, 0>(s));
+ set<1>(result.intersections[0], get<0, 1>(s));
+ return result;
+ }
+};
+
+
+}} // namespace policies::relate
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
diff --git a/src/boost/geometry/policies/relate/intersection_points_slope.hpp b/src/boost/geometry/policies/relate/intersection_points_slope.hpp
new file mode 100644
index 0000000..b5c9922
--- /dev/null
+++ b/src/boost/geometry/policies/relate/intersection_points_slope.hpp
@@ -0,0 +1,213 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+
+
+#include <string>
+
+#include <boost/concept_check.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/strategies/side_info.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace policies { namespace relate
+{
+
+
+template <typename S1, typename S2, typename ReturnType, typename CalculationType = void>
+struct segments_intersection_points
+{
+ typedef ReturnType return_type;
+ typedef S1 segment_type1;
+ typedef S2 segment_type2;
+ typedef typename select_calculation_type
+ <
+ S1, S2, CalculationType
+ >::type coordinate_type;
+
+ // Get the same type, but at least a double (also used for divisions
+ typedef typename select_most_precise
+ <
+ coordinate_type, double
+ >::type promoted_type;
+
+ template <int Dimension>
+ static inline return_type rico(
+ coordinate_type const& dm1, coordinate_type const& dn1,
+ coordinate_type const& dm2, coordinate_type const& dn2,
+ S1 const& s1, S2 const& s2)
+ {
+ promoted_type const a1 = dn1 / dm1;
+ promoted_type const a2 = dn2 / dm2;
+ promoted_type const da = a1 - a2;
+
+ if (math::equals(da, 0))
+ {
+ return rico<1 - Dimension>(dn1, dm1, dn2, dm2, s1, s2);
+ }
+
+ promoted_type const b1 = get<0, Dimension>(s1) - a1 * get<0, 1 - Dimension>(s1);
+ promoted_type const b2 = get<0, Dimension>(s2) - a2 * get<0, 1 - Dimension>(s2);
+
+ promoted_type const v = (b2 - b1) / da;
+
+ return_type result;
+ result.count = 1;
+ set<1 - Dimension>(result.intersections[0],
+ boost::numeric_cast<coordinate_type>(v));
+ set<Dimension>(result.intersections[0],
+ boost::numeric_cast<coordinate_type>(a1 * v + b1));
+ return result;
+ }
+
+ static inline return_type cross(S1 const& s1, S2 const& s2)
+ {
+ // Take one of first segment, and one of second segment
+ return_type result;
+ result.count = 1;
+ set<0>(result.intersections[0], get<0, 0>(s1));
+ set<1>(result.intersections[0], get<0, 1>(s2));
+ return result;
+ }
+
+
+ static inline return_type segments_intersect(side_info const& sides,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ coordinate_type const& dx2, coordinate_type const& dy2,
+ S1 const& s1, S2 const& s2)
+ {
+ bool vertical1 = math::equals(dx1, 0);
+ bool horizontal2 = math::equals(dy2, 0);
+ if (vertical1 && horizontal2)
+ {
+ return cross(s1, s2);
+ }
+
+ bool vertical2 = math::equals(dx2, 0);
+ bool horizontal1 = math::equals(dy1, 0);
+ if (horizontal1 && vertical2)
+ {
+ return cross(s2, s1);
+ }
+ if (vertical1 || vertical2)
+ {
+ return rico<0>(dy1, dx1, dy2, dx2, s1, s2);
+ }
+ else
+ {
+ // Not crossing, take the most reasonable choice.
+ // We want to divide by the largest one.
+ //if (
+
+ return rico<1>(dx1, dy1, dx2, dy2, s1, s2);
+ }
+ }
+
+ static inline return_type collinear_touch(coordinate_type const& x,
+ coordinate_type const& y, bool, char)
+ {
+ return_type result;
+ result.count = 1;
+ set<0>(result.intersections[0], x);
+ set<1>(result.intersections[0], y);
+ return result;
+ }
+
+ template <typename S>
+ static inline return_type collinear_inside(S const& s)
+ {
+ return_type result;
+ result.count = 2;
+ set<0>(result.intersections[0], get<0, 0>(s));
+ set<1>(result.intersections[0], get<0, 1>(s));
+ set<0>(result.intersections[1], get<1, 0>(s));
+ set<1>(result.intersections[1], get<1, 1>(s));
+ return result;
+ }
+
+ template <typename S>
+ static inline return_type collinear_interior_boundary_intersect(S const& s, bool, bool)
+ {
+ return collinear_inside(s);
+ }
+
+ static inline return_type collinear_a_in_b(S1 const& s, bool)
+ {
+ return collinear_inside(s);
+ }
+ static inline return_type collinear_b_in_a(S2 const& s, bool)
+ {
+ return collinear_inside(s);
+ }
+
+ static inline return_type collinear_overlaps(
+ coordinate_type const& x1, coordinate_type const& y1,
+ coordinate_type const& x2, coordinate_type const& y2, bool)
+ {
+ return_type result;
+ result.count = 2;
+ set<0>(result.intersections[0], x1);
+ set<1>(result.intersections[0], y1);
+ set<0>(result.intersections[1], x2);
+ set<1>(result.intersections[1], y2);
+ return result;
+ }
+
+ static inline return_type segment_equal(S1 const& s, bool)
+ {
+ return_type result;
+ result.count = 2;
+ set<0>(result.intersections[0], get<0, 0>(s));
+ set<1>(result.intersections[0], get<0, 1>(s));
+ set<0>(result.intersections[1], get<1, 0>(s));
+ set<1>(result.intersections[1], get<1, 1>(s));
+ return result;
+ }
+
+ static inline return_type disjoint()
+ {
+ return return_type();
+ }
+ static inline return_type error(std::string const& msg)
+ {
+ return return_type();
+ }
+
+ static inline return_type collinear_disjoint()
+ {
+ return return_type();
+ }
+ static inline return_type parallel()
+ {
+ return return_type();
+ }
+ static inline return_type degenerate(S1 const& s, bool)
+ {
+ return_type result;
+ result.count = 1;
+ set<0>(result.intersections[0], get<0, 0>(s));
+ set<1>(result.intersections[0], get<0, 1>(s));
+ return result;
+ }
+};
+
+
+}} // namespace policies::relate
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
diff --git a/src/boost/geometry/policies/relate/tupled.hpp b/src/boost/geometry/policies/relate/tupled.hpp
new file mode 100644
index 0000000..f6713c4
--- /dev/null
+++ b/src/boost/geometry/policies/relate/tupled.hpp
@@ -0,0 +1,175 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
+#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
+
+
+#include <string>
+
+#include <boost/tuple/tuple.hpp>
+#include <boost/geometry/strategies/side_info.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace policies { namespace relate
+{
+
+
+// "tupled" to return intersection results together.
+// Now with two, with some meta-programming and derivations it can also be three (or more)
+template <typename Policy1, typename Policy2, typename CalculationType = void>
+struct segments_tupled
+{
+ typedef boost::tuple
+ <
+ typename Policy1::return_type,
+ typename Policy2::return_type
+ > return_type;
+
+ // Take segments of first policy, they should be equal
+ typedef typename Policy1::segment_type1 segment_type1;
+ typedef typename Policy1::segment_type2 segment_type2;
+
+ typedef typename select_calculation_type
+ <
+ segment_type1,
+ segment_type2,
+ CalculationType
+ >::type coordinate_type;
+
+ // Get the same type, but at least a double
+ typedef typename select_most_precise<coordinate_type, double>::type rtype;
+
+ template <typename R>
+ static inline return_type segments_intersect(side_info const& sides,
+ R const& r,
+ coordinate_type const& dx1, coordinate_type const& dy1,
+ coordinate_type const& dx2, coordinate_type const& dy2,
+ segment_type1 const& s1, segment_type2 const& s2)
+ {
+ return boost::make_tuple
+ (
+ Policy1::segments_intersect(sides, r,
+ dx1, dy1, dx2, dy2, s1, s2),
+ Policy2::segments_intersect(sides, r,
+ dx1, dy1, dx2, dy2, s1, s2)
+ );
+ }
+
+ static inline return_type collinear_touch(coordinate_type const& x,
+ coordinate_type const& y, int arrival_a, int arrival_b)
+ {
+ return boost::make_tuple
+ (
+ Policy1::collinear_touch(x, y, arrival_a, arrival_b),
+ Policy2::collinear_touch(x, y, arrival_a, arrival_b)
+ );
+ }
+
+ template <typename S>
+ static inline return_type collinear_interior_boundary_intersect(S const& segment,
+ bool a_within_b,
+ int arrival_a, int arrival_b, bool opposite)
+ {
+ return boost::make_tuple
+ (
+ Policy1::collinear_interior_boundary_intersect(segment, a_within_b, arrival_a, arrival_b, opposite),
+ Policy2::collinear_interior_boundary_intersect(segment, a_within_b, arrival_a, arrival_b, opposite)
+ );
+ }
+
+ static inline return_type collinear_a_in_b(segment_type1 const& segment,
+ bool opposite)
+ {
+ return boost::make_tuple
+ (
+ Policy1::collinear_a_in_b(segment, opposite),
+ Policy2::collinear_a_in_b(segment, opposite)
+ );
+ }
+ static inline return_type collinear_b_in_a(segment_type2 const& segment,
+ bool opposite)
+ {
+ return boost::make_tuple
+ (
+ Policy1::collinear_b_in_a(segment, opposite),
+ Policy2::collinear_b_in_a(segment, opposite)
+ );
+ }
+
+
+ static inline return_type collinear_overlaps(
+ coordinate_type const& x1, coordinate_type const& y1,
+ coordinate_type const& x2, coordinate_type const& y2,
+ int arrival_a, int arrival_b, bool opposite)
+ {
+ return boost::make_tuple
+ (
+ Policy1::collinear_overlaps(x1, y1, x2, y2, arrival_a, arrival_b, opposite),
+ Policy2::collinear_overlaps(x1, y1, x2, y2, arrival_a, arrival_b, opposite)
+ );
+ }
+
+ static inline return_type segment_equal(segment_type1 const& s,
+ bool opposite)
+ {
+ return boost::make_tuple
+ (
+ Policy1::segment_equal(s, opposite),
+ Policy2::segment_equal(s, opposite)
+ );
+ }
+
+ static inline return_type degenerate(segment_type1 const& segment,
+ bool a_degenerate)
+ {
+ return boost::make_tuple
+ (
+ Policy1::degenerate(segment, a_degenerate),
+ Policy2::degenerate(segment, a_degenerate)
+ );
+ }
+
+ static inline return_type disjoint()
+ {
+ return boost::make_tuple
+ (
+ Policy1::disjoint(),
+ Policy2::disjoint()
+ );
+ }
+
+ static inline return_type error(std::string const& msg)
+ {
+ return boost::make_tuple
+ (
+ Policy1::error(msg),
+ Policy2::error(msg)
+ );
+ }
+
+ static inline return_type collinear_disjoint()
+ {
+ return boost::make_tuple
+ (
+ Policy1::collinear_disjoint(),
+ Policy2::collinear_disjoint()
+ );
+ }
+
+};
+
+}} // namespace policies::relate
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
diff --git a/src/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp b/src/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
new file mode 100644
index 0000000..747c140
--- /dev/null
+++ b/src/boost/geometry/strategies/agnostic/hull_graham_andrew.hpp
@@ -0,0 +1,384 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
+#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
+
+
+#include <cstddef>
+#include <algorithm>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/strategies/convex_hull.hpp>
+
+#include <boost/geometry/views/detail/range_type.hpp>
+
+#include <boost/geometry/policies/compare.hpp>
+
+#include <boost/geometry/algorithms/detail/for_each_range.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace convex_hull
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template
+<
+ typename InputRange,
+ typename RangeIterator,
+ typename StrategyLess,
+ typename StrategyGreater
+>
+struct get_extremes
+{
+ typedef typename point_type<InputRange>::type point_type;
+
+ point_type left, right;
+
+ bool first;
+
+ StrategyLess less;
+ StrategyGreater greater;
+
+ inline get_extremes()
+ : first(true)
+ {}
+
+ inline void apply(InputRange const& range)
+ {
+ if (boost::size(range) == 0)
+ {
+ return;
+ }
+
+ // First iterate through this range
+ // (this two-stage approach avoids many point copies,
+ // because iterators are kept in memory. Because iterators are
+ // not persistent (in MSVC) this approach is not applicable
+ // for more ranges together)
+
+ RangeIterator left_it = boost::begin(range);
+ RangeIterator right_it = boost::begin(range);
+
+ for (RangeIterator it = boost::begin(range) + 1;
+ it != boost::end(range);
+ ++it)
+ {
+ if (less(*it, *left_it))
+ {
+ left_it = it;
+ }
+
+ if (greater(*it, *right_it))
+ {
+ right_it = it;
+ }
+ }
+
+ // Then compare with earlier
+ if (first)
+ {
+ // First time, assign left/right
+ left = *left_it;
+ right = *right_it;
+ first = false;
+ }
+ else
+ {
+ // Next time, check if this range was left/right from
+ // the extremes already collected
+ if (less(*left_it, left))
+ {
+ left = *left_it;
+ }
+
+ if (greater(*right_it, right))
+ {
+ right = *right_it;
+ }
+ }
+ }
+};
+
+
+template
+<
+ typename InputRange,
+ typename RangeIterator,
+ typename Container,
+ typename SideStrategy
+>
+struct assign_range
+{
+ Container lower_points, upper_points;
+
+ typedef typename point_type<InputRange>::type point_type;
+
+ point_type const& most_left;
+ point_type const& most_right;
+
+ inline assign_range(point_type const& left, point_type const& right)
+ : most_left(left)
+ , most_right(right)
+ {}
+
+ inline void apply(InputRange const& range)
+ {
+ typedef SideStrategy side;
+
+ // Put points in one of the two output sequences
+ for (RangeIterator it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ // check if it is lying most_left or most_right from the line
+
+ int dir = side::apply(most_left, most_right, *it);
+ switch(dir)
+ {
+ case 1 : // left side
+ upper_points.push_back(*it);
+ break;
+ case -1 : // right side
+ lower_points.push_back(*it);
+ break;
+
+ // 0: on line most_left-most_right,
+ // or most_left, or most_right,
+ // -> all never part of hull
+ }
+ }
+ }
+};
+
+template <typename Range>
+static inline void sort(Range& range)
+{
+ typedef typename boost::range_value<Range>::type point_type;
+ typedef geometry::less<point_type> comparator;
+
+ std::sort(boost::begin(range), boost::end(range), comparator());
+}
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Graham scan strategy to calculate convex hull
+\ingroup strategies
+\note Completely reworked version inspired on the sources listed below
+\see http://www.ddj.com/architect/201806315
+\see http://marknelson.us/2007/08/22/convex
+ */
+template <typename InputGeometry, typename OutputPoint>
+class graham_andrew
+{
+public :
+ typedef OutputPoint point_type;
+ typedef InputGeometry geometry_type;
+
+private:
+
+ typedef typename cs_tag<point_type>::type cs_tag;
+
+ typedef typename std::vector<point_type> container_type;
+ typedef typename std::vector<point_type>::const_iterator iterator;
+ typedef typename std::vector<point_type>::const_reverse_iterator rev_iterator;
+
+
+ class partitions
+ {
+ friend class graham_andrew;
+
+ container_type m_lower_hull;
+ container_type m_upper_hull;
+ container_type m_copied_input;
+ };
+
+
+public:
+ typedef partitions state_type;
+
+
+ inline void apply(InputGeometry const& geometry, partitions& state) const
+ {
+ // First pass.
+ // Get min/max (in most cases left / right) points
+ // This makes use of the geometry::less/greater predicates
+
+ // For the left boundary it is important that multiple points
+ // are sorted from bottom to top. Therefore the less predicate
+ // does not take the x-only template parameter (this fixes ticket #6019.
+ // For the right boundary it is not necessary (though also not harmful),
+ // because points are sorted from bottom to top in a later stage.
+ // For symmetry and to get often more balanced lower/upper halves
+ // we keep it.
+
+ typedef typename geometry::detail::range_type<InputGeometry>::type range_type;
+
+ typedef typename boost::range_iterator
+ <
+ range_type const
+ >::type range_iterator;
+
+ detail::get_extremes
+ <
+ range_type,
+ range_iterator,
+ geometry::less<point_type>,
+ geometry::greater<point_type>
+ > extremes;
+ geometry::detail::for_each_range(geometry, extremes);
+
+ // Bounding left/right points
+ // Second pass, now that extremes are found, assign all points
+ // in either lower, either upper
+ detail::assign_range
+ <
+ range_type,
+ range_iterator,
+ container_type,
+ typename strategy::side::services::default_strategy<cs_tag>::type
+ > assigner(extremes.left, extremes.right);
+
+ geometry::detail::for_each_range(geometry, assigner);
+
+
+ // Sort both collections, first on x(, then on y)
+ detail::sort(assigner.lower_points);
+ detail::sort(assigner.upper_points);
+
+ //std::cout << boost::size(assigner.lower_points) << std::endl;
+ //std::cout << boost::size(assigner.upper_points) << std::endl;
+
+ // And decide which point should be in the final hull
+ build_half_hull<-1>(assigner.lower_points, state.m_lower_hull,
+ extremes.left, extremes.right);
+ build_half_hull<1>(assigner.upper_points, state.m_upper_hull,
+ extremes.left, extremes.right);
+ }
+
+
+ template <typename OutputIterator>
+ inline void result(partitions const& state,
+ OutputIterator out, bool clockwise) const
+ {
+ if (clockwise)
+ {
+ output_range<iterate_forward>(state.m_upper_hull, out, false);
+ output_range<iterate_reverse>(state.m_lower_hull, out, true);
+ }
+ else
+ {
+ output_range<iterate_forward>(state.m_lower_hull, out, false);
+ output_range<iterate_reverse>(state.m_upper_hull, out, true);
+ }
+ }
+
+
+private:
+
+ template <int Factor>
+ static inline void build_half_hull(container_type const& input,
+ container_type& output,
+ point_type const& left, point_type const& right)
+ {
+ output.push_back(left);
+ for(iterator it = input.begin(); it != input.end(); ++it)
+ {
+ add_to_hull<Factor>(*it, output);
+ }
+ add_to_hull<Factor>(right, output);
+ }
+
+
+ template <int Factor>
+ static inline void add_to_hull(point_type const& p, container_type& output)
+ {
+ typedef typename strategy::side::services::default_strategy<cs_tag>::type side;
+
+ output.push_back(p);
+ register std::size_t output_size = output.size();
+ while (output_size >= 3)
+ {
+ rev_iterator rit = output.rbegin();
+ point_type const& last = *rit++;
+ point_type const& last2 = *rit++;
+
+ if (Factor * side::apply(*rit, last, last2) <= 0)
+ {
+ // Remove last two points from stack, and add last again
+ // This is much faster then erasing the one but last.
+ output.pop_back();
+ output.pop_back();
+ output.push_back(last);
+ output_size--;
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+
+
+ template <iterate_direction Direction, typename OutputIterator>
+ static inline void output_range(container_type const& range,
+ OutputIterator out, bool skip_first)
+ {
+ typedef typename reversible_view<container_type const, Direction>::type view_type;
+ view_type view(range);
+ bool first = true;
+ for (typename boost::range_iterator<view_type const>::type it = boost::begin(view);
+ it != boost::end(view); ++it)
+ {
+ if (first && skip_first)
+ {
+ first = false;
+ }
+ else
+ {
+ *out = *it;
+ ++out;
+ }
+ }
+ }
+
+};
+
+}} // namespace strategy::convex_hull
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename InputGeometry, typename OutputPoint>
+struct strategy_convex_hull<InputGeometry, OutputPoint, cartesian_tag>
+{
+ typedef strategy::convex_hull::graham_andrew<InputGeometry, OutputPoint> type;
+};
+#endif
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
diff --git a/src/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp b/src/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp
new file mode 100644
index 0000000..1398ddb
--- /dev/null
+++ b/src/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp
@@ -0,0 +1,151 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
+
+#include <boost/array.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy
+{
+
+namespace within
+{
+
+struct decide_within
+{
+ static inline bool apply(int side, bool& result)
+ {
+ if (side != 1)
+ {
+ result = false;
+ return false;
+ }
+ return true; // continue
+ }
+};
+
+struct decide_covered_by
+{
+ static inline bool apply(int side, bool& result)
+ {
+ if (side != 1)
+ {
+ result = side >= 0;
+ return false;
+ }
+ return true; // continue
+ }
+};
+
+
+template <typename Point, typename Box, typename Decide = decide_within>
+struct point_in_box_by_side
+{
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Box>::type
+ >::type side_strategy_type;
+
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ // Create (counterclockwise) array of points, the fifth one closes it
+ // Every point should be on the LEFT side (=1), or ON the border (=0),
+ // So >= 1 or >= 0
+ boost::array<typename point_type<Box>::type, 5> bp;
+ geometry::detail::assign_box_corners_oriented<true>(box, bp);
+ bp[4] = bp[0];
+
+ bool result = true;
+ side_strategy_type strategy;
+ boost::ignore_unused_variable_warning(strategy);
+
+ for (int i = 1; i < 5; i++)
+ {
+ int const side = strategy.apply(point, bp[i - 1], bp[i]);
+ if (! Decide::apply(side, result))
+ {
+ return result;
+ }
+ }
+
+ return result;
+ }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag,
+ point_tag, areal_tag,
+ spherical_tag, spherical_tag,
+ Point, Box
+ >
+{
+ typedef within::point_in_box_by_side
+ <
+ Point, Box, within::decide_within
+ > type;
+};
+
+
+
+}} // namespace within::services
+
+
+namespace covered_by { namespace services
+{
+
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag,
+ point_tag, areal_tag,
+ spherical_tag, spherical_tag,
+ Point, Box
+ >
+{
+ typedef within::point_in_box_by_side
+ <
+ Point, Box, within::decide_covered_by
+ > type;
+};
+
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
diff --git a/src/boost/geometry/strategies/agnostic/point_in_poly_oriented_winding.hpp b/src/boost/geometry/strategies/agnostic/point_in_poly_oriented_winding.hpp
new file mode 100644
index 0000000..423948f
--- /dev/null
+++ b/src/boost/geometry/strategies/agnostic/point_in_poly_oriented_winding.hpp
@@ -0,0 +1,208 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_ORIENTED_WINDING_HPP
+#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_ORIENTED_WINDING_HPP
+
+
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace within
+{
+
+/*!
+\brief Within detection using winding rule, but checking if enclosing ring is
+ counter clockwise and, if so, reverses the result
+\ingroup strategies
+\tparam Point \tparam_point
+\tparam Reverse True if parameter should be reversed
+\tparam PointOfSegment \tparam_segment_point
+\tparam CalculationType \tparam_calculation
+\author Barend Gehrels
+\note The implementation is inspired by terralib http://www.terralib.org (LGPL)
+\note but totally revised afterwards, especially for cases on segments
+\note Only dependant on "side", -> agnostic, suitable for spherical/latlong
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
+}
+ */
+template
+<
+ bool Reverse,
+ typename Point,
+ typename PointOfSegment = Point,
+ typename CalculationType = void
+>
+class oriented_winding
+{
+ typedef typename select_calculation_type
+ <
+ Point,
+ PointOfSegment,
+ CalculationType
+ >::type calculation_type;
+
+
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Point>::type
+ >::type strategy_side_type;
+
+
+ /*! subclass to keep state */
+ class counter
+ {
+ int m_count;
+ bool m_touches;
+ calculation_type m_sum_area;
+
+ inline int code() const
+ {
+ return m_touches ? 0 : m_count == 0 ? -1 : 1;
+ }
+ inline int clockwise_oriented_code() const
+ {
+ return (m_sum_area > 0) ? code() : -code();
+ }
+ inline int oriented_code() const
+ {
+ return Reverse
+ ? -clockwise_oriented_code()
+ : clockwise_oriented_code();
+ }
+
+ public :
+ friend class oriented_winding;
+
+ inline counter()
+ : m_count(0)
+ , m_touches(false)
+ , m_sum_area(0)
+ {}
+
+ inline void add_to_area(calculation_type triangle)
+ {
+ m_sum_area += triangle;
+ }
+
+ };
+
+
+ template <size_t D>
+ static inline int check_touch(Point const& point,
+ PointOfSegment const& seg1, PointOfSegment const& seg2,
+ counter& state)
+ {
+ calculation_type const p = get<D>(point);
+ calculation_type const s1 = get<D>(seg1);
+ calculation_type const s2 = get<D>(seg2);
+ if ((s1 <= p && s2 >= p) || (s2 <= p && s1 >= p))
+ {
+ state.m_touches = true;
+ }
+ return 0;
+ }
+
+
+ template <size_t D>
+ static inline int check_segment(Point const& point,
+ PointOfSegment const& seg1, PointOfSegment const& seg2,
+ counter& state)
+ {
+ calculation_type const p = get<D>(point);
+ calculation_type const s1 = get<D>(seg1);
+ calculation_type const s2 = get<D>(seg2);
+
+
+ // Check if one of segment endpoints is at same level of point
+ bool eq1 = math::equals(s1, p);
+ bool eq2 = math::equals(s2, p);
+
+ if (eq1 && eq2)
+ {
+ // Both equal p -> segment is horizontal (or vertical for D=0)
+ // The only thing which has to be done is check if point is ON segment
+ return check_touch<1 - D>(point, seg1, seg2, state);
+ }
+
+ return
+ eq1 ? (s2 > p ? 1 : -1) // Point on level s1, UP/DOWN depending on s2
+ : eq2 ? (s1 > p ? -1 : 1) // idem
+ : s1 < p && s2 > p ? 2 // Point between s1 -> s2 --> UP
+ : s2 < p && s1 > p ? -2 // Point between s2 -> s1 --> DOWN
+ : 0;
+ }
+
+
+
+
+public :
+
+ // Typedefs and static methods to fulfill the concept
+ typedef Point point_type;
+ typedef PointOfSegment segment_point_type;
+ typedef counter state_type;
+
+ static inline bool apply(Point const& point,
+ PointOfSegment const& s1, PointOfSegment const& s2,
+ counter& state)
+ {
+ state.add_to_area(get<0>(s2) * get<1>(s1) - get<0>(s1) * get<1>(s2));
+
+ int count = check_segment<1>(point, s1, s2, state);
+ if (count != 0)
+ {
+ int side = strategy_side_type::apply(s1, s2, point);
+ if (side == 0)
+ {
+ // Point is lying on segment
+ state.m_touches = true;
+ state.m_count = 0;
+ return false;
+ }
+
+ // Side is NEG for right, POS for left.
+ // The count is -2 for down, 2 for up (or -1/1)
+ // Side positive thus means UP and LEFTSIDE or DOWN and RIGHTSIDE
+ // See accompagnying figure (TODO)
+ if (side * count > 0)
+ {
+ state.m_count += count;
+ }
+ }
+ return ! state.m_touches;
+ }
+
+ static inline int result(counter const& state)
+ {
+ return state.oriented_code();
+ }
+};
+
+
+}} // namespace strategy::within
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_ORIENTED_WINDING_HPP
diff --git a/src/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp b/src/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
new file mode 100644
index 0000000..6918865
--- /dev/null
+++ b/src/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
@@ -0,0 +1,232 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
+#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
+
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace within
+{
+
+/*!
+\brief Within detection using winding rule
+\ingroup strategies
+\tparam Point \tparam_point
+\tparam PointOfSegment \tparam_segment_point
+\tparam CalculationType \tparam_calculation
+\author Barend Gehrels
+\note The implementation is inspired by terralib http://www.terralib.org (LGPL)
+\note but totally revised afterwards, especially for cases on segments
+\note Only dependant on "side", -> agnostic, suitable for spherical/latlong
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
+}
+ */
+template
+<
+ typename Point,
+ typename PointOfSegment = Point,
+ typename CalculationType = void
+>
+class winding
+{
+ typedef typename select_calculation_type
+ <
+ Point,
+ PointOfSegment,
+ CalculationType
+ >::type calculation_type;
+
+
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Point>::type
+ >::type strategy_side_type;
+
+
+ /*! subclass to keep state */
+ class counter
+ {
+ int m_count;
+ bool m_touches;
+
+ inline int code() const
+ {
+ return m_touches ? 0 : m_count == 0 ? -1 : 1;
+ }
+
+ public :
+ friend class winding;
+
+ inline counter()
+ : m_count(0)
+ , m_touches(false)
+ {}
+
+ };
+
+
+ template <size_t D>
+ static inline int check_touch(Point const& point,
+ PointOfSegment const& seg1, PointOfSegment const& seg2,
+ counter& state)
+ {
+ calculation_type const p = get<D>(point);
+ calculation_type const s1 = get<D>(seg1);
+ calculation_type const s2 = get<D>(seg2);
+ if ((s1 <= p && s2 >= p) || (s2 <= p && s1 >= p))
+ {
+ state.m_touches = true;
+ }
+ return 0;
+ }
+
+
+ template <size_t D>
+ static inline int check_segment(Point const& point,
+ PointOfSegment const& seg1, PointOfSegment const& seg2,
+ counter& state)
+ {
+ calculation_type const p = get<D>(point);
+ calculation_type const s1 = get<D>(seg1);
+ calculation_type const s2 = get<D>(seg2);
+
+ // Check if one of segment endpoints is at same level of point
+ bool eq1 = math::equals(s1, p);
+ bool eq2 = math::equals(s2, p);
+
+ if (eq1 && eq2)
+ {
+ // Both equal p -> segment is horizontal (or vertical for D=0)
+ // The only thing which has to be done is check if point is ON segment
+ return check_touch<1 - D>(point, seg1, seg2,state);
+ }
+
+ return
+ eq1 ? (s2 > p ? 1 : -1) // Point on level s1, UP/DOWN depending on s2
+ : eq2 ? (s1 > p ? -1 : 1) // idem
+ : s1 < p && s2 > p ? 2 // Point between s1 -> s2 --> UP
+ : s2 < p && s1 > p ? -2 // Point between s2 -> s1 --> DOWN
+ : 0;
+ }
+
+
+
+
+public :
+
+ // Typedefs and static methods to fulfill the concept
+ typedef Point point_type;
+ typedef PointOfSegment segment_point_type;
+ typedef counter state_type;
+
+ static inline bool apply(Point const& point,
+ PointOfSegment const& s1, PointOfSegment const& s2,
+ counter& state)
+ {
+ int count = check_segment<1>(point, s1, s2, state);
+ if (count != 0)
+ {
+ int side = strategy_side_type::apply(s1, s2, point);
+ if (side == 0)
+ {
+ // Point is lying on segment
+ state.m_touches = true;
+ state.m_count = 0;
+ return false;
+ }
+
+ // Side is NEG for right, POS for left.
+ // The count is -2 for down, 2 for up (or -1/1)
+ // Side positive thus means UP and LEFTSIDE or DOWN and RIGHTSIDE
+ // See accompagnying figure (TODO)
+ if (side * count > 0)
+ {
+ state.m_count += count;
+ }
+ }
+ return ! state.m_touches;
+ }
+
+ static inline int result(counter const& state)
+ {
+ return state.code();
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+// Register using "areal_tag" for ring, polygon, multi-polygon
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, cartesian_tag, cartesian_tag, Point, Geometry>
+{
+ typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
+};
+
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag, spherical_tag, Point, Geometry>
+{
+ typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
+};
+
+
+} // namespace services
+
+#endif
+
+
+}} // namespace strategy::within
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace strategy { namespace covered_by { namespace services
+{
+
+// Register using "areal_tag" for ring, polygon, multi-polygon
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, cartesian_tag, cartesian_tag, Point, Geometry>
+{
+ typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
+};
+
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag, spherical_tag, Point, Geometry>
+{
+ typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
+};
+
+
+}}} // namespace strategy::covered_by::services
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
diff --git a/src/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp b/src/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp
new file mode 100644
index 0000000..4a1a22d
--- /dev/null
+++ b/src/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp
@@ -0,0 +1,229 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 1995, 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 1995 Maarten Hilferink, Amsterdam, the Netherlands
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP
+#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP
+
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+
+
+
+//#define GL_DEBUG_DOUGLAS_PEUCKER
+
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+#include <boost/geometry/io/dsv/write.hpp>
+#endif
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace simplify
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+ /*!
+ \brief Small wrapper around a point, with an extra member "included"
+ \details
+ It has a const-reference to the original point (so no copy here)
+ \tparam the enclosed point type
+ */
+ template<typename Point>
+ struct douglas_peucker_point
+ {
+ Point const& p;
+ bool included;
+
+ inline douglas_peucker_point(Point const& ap)
+ : p(ap)
+ , included(false)
+ {}
+
+ // Necessary for proper compilation
+ inline douglas_peucker_point<Point> operator=(douglas_peucker_point<Point> const& )
+ {
+ return douglas_peucker_point<Point>(*this);
+ }
+ };
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Implements the simplify algorithm.
+\ingroup strategies
+\details The douglas_peucker strategy simplifies a linestring, ring or
+ vector of points using the well-known Douglas-Peucker algorithm.
+ For the algorithm, see for example:
+\see http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
+\see http://www2.dcs.hull.ac.uk/CISRG/projects/Royal-Inst/demos/dp.html
+\tparam Point the point type
+\tparam PointDistanceStrategy point-segment distance strategy to be used
+\note This strategy uses itself a point-segment-distance strategy which
+ can be specified
+\author Barend and Maarten, 1995/1996
+\author Barend, revised for Generic Geometry Library, 2008
+*/
+template
+<
+ typename Point,
+ typename PointDistanceStrategy
+>
+class douglas_peucker
+{
+public :
+
+ // See also ticket 5954 https://svn.boost.org/trac/boost/ticket/5954
+ // Comparable is currently not possible here because it has to be compared to the squared of max_distance, and more.
+ // For now we have to take the real distance.
+ typedef PointDistanceStrategy distance_strategy_type;
+ // typedef typename strategy::distance::services::comparable_type<PointDistanceStrategy>::type distance_strategy_type;
+
+ typedef typename strategy::distance::services::return_type<distance_strategy_type>::type return_type;
+
+private :
+ typedef detail::douglas_peucker_point<Point> dp_point_type;
+ typedef typename std::vector<dp_point_type>::iterator iterator_type;
+
+
+ static inline void consider(iterator_type begin,
+ iterator_type end,
+ return_type const& max_dist, int& n,
+ distance_strategy_type const& ps_distance_strategy)
+ {
+ std::size_t size = end - begin;
+
+ // size must be at least 3
+ // because we want to consider a candidate point in between
+ if (size <= 2)
+ {
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+ if (begin != end)
+ {
+ std::cout << "ignore between " << dsv(begin->p)
+ << " and " << dsv((end - 1)->p)
+ << " size=" << size << std::endl;
+ }
+ std::cout << "return because size=" << size << std::endl;
+#endif
+ return;
+ }
+
+ iterator_type last = end - 1;
+
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+ std::cout << "find between " << dsv(begin->p)
+ << " and " << dsv(last->p)
+ << " size=" << size << std::endl;
+#endif
+
+
+ // Find most far point, compare to the current segment
+ //geometry::segment<Point const> s(begin->p, last->p);
+ return_type md(-1.0); // any value < 0
+ iterator_type candidate;
+ for(iterator_type it = begin + 1; it != last; ++it)
+ {
+ return_type dist = ps_distance_strategy.apply(it->p, begin->p, last->p);
+
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+ std::cout << "consider " << dsv(it->p)
+ << " at " << double(dist)
+ << ((dist > max_dist) ? " maybe" : " no")
+ << std::endl;
+
+#endif
+ if (dist > md)
+ {
+ md = dist;
+ candidate = it;
+ }
+ }
+
+ // If a point is found, set the include flag
+ // and handle segments in between recursively
+ if (md > max_dist)
+ {
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+ std::cout << "use " << dsv(candidate->p) << std::endl;
+#endif
+
+ candidate->included = true;
+ n++;
+
+ consider(begin, candidate + 1, max_dist, n, ps_distance_strategy);
+ consider(candidate, end, max_dist, n, ps_distance_strategy);
+ }
+ }
+
+
+public :
+
+ template <typename Range, typename OutputIterator>
+ static inline OutputIterator apply(Range const& range,
+ OutputIterator out, double max_distance)
+ {
+ distance_strategy_type strategy;
+
+ // Copy coordinates, a vector of references to all points
+ std::vector<dp_point_type> ref_candidates(boost::begin(range),
+ boost::end(range));
+
+ // Include first and last point of line,
+ // they are always part of the line
+ int n = 2;
+ ref_candidates.front().included = true;
+ ref_candidates.back().included = true;
+
+ // Get points, recursively, including them if they are further away
+ // than the specified distance
+ typedef typename strategy::distance::services::return_type<distance_strategy_type>::type return_type;
+
+ consider(boost::begin(ref_candidates), boost::end(ref_candidates), max_distance, n, strategy);
+
+ // Copy included elements to the output
+ for(typename std::vector<dp_point_type>::const_iterator it
+ = boost::begin(ref_candidates);
+ it != boost::end(ref_candidates);
+ ++it)
+ {
+ if (it->included)
+ {
+ // copy-coordinates does not work because OutputIterator
+ // does not model Point (??)
+ //geometry::convert(it->p, *out);
+ *out = it->p;
+ out++;
+ }
+ }
+ return out;
+ }
+
+};
+
+}} // namespace strategy::simplify
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP
diff --git a/src/boost/geometry/strategies/area.hpp b/src/boost/geometry/strategies/area.hpp
new file mode 100644
index 0000000..e192d9b
--- /dev/null
+++ b/src/boost/geometry/strategies/area.hpp
@@ -0,0 +1,50 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_AREA_HPP
+#define BOOST_GEOMETRY_STRATEGIES_AREA_HPP
+
+#include <boost/mpl/assert.hpp>
+
+#include <boost/geometry/strategies/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace area { namespace services
+{
+
+/*!
+ \brief Traits class binding a default area strategy to a coordinate system
+ \ingroup area
+ \tparam Tag tag of coordinate system
+ \tparam PointOfSegment point-type
+*/
+template <typename Tag, typename PointOfSegment>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE
+ , (types<PointOfSegment>)
+ );
+};
+
+
+}}} // namespace strategy::area::services
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_AREA_HPP
diff --git a/src/boost/geometry/strategies/cartesian/area_surveyor.hpp b/src/boost/geometry/strategies/cartesian/area_surveyor.hpp
new file mode 100644
index 0000000..74b6353
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/area_surveyor.hpp
@@ -0,0 +1,134 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
+
+
+#include <boost/mpl/if.hpp>
+
+#include <boost/geometry/arithmetic/determinant.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace area
+{
+
+/*!
+\brief Area calculation for cartesian points
+\ingroup strategies
+\details Calculates area using the Surveyor's formula, a well-known
+ triangulation algorithm
+\tparam PointOfSegment \tparam_segment_point
+\tparam CalculationType \tparam_calculation
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
+}
+
+*/
+template
+<
+ typename PointOfSegment,
+ typename CalculationType = void
+>
+class surveyor
+{
+public :
+ // If user specified a calculation type, use that type,
+ // whatever it is and whatever the point-type is.
+ // Else, use the pointtype, but at least double
+ typedef typename
+ boost::mpl::if_c
+ <
+ boost::is_void<CalculationType>::type::value,
+ typename select_most_precise
+ <
+ typename coordinate_type<PointOfSegment>::type,
+ double
+ >::type,
+ CalculationType
+ >::type return_type;
+
+
+private :
+
+ class summation
+ {
+ friend class surveyor;
+
+ return_type sum;
+ public :
+
+ inline summation() : sum(return_type())
+ {
+ // Strategy supports only 2D areas
+ assert_dimension<PointOfSegment, 2>();
+ }
+ inline return_type area() const
+ {
+ return_type result = sum;
+ return_type const two = 2;
+ result /= two;
+ return result;
+ }
+ };
+
+public :
+ typedef summation state_type;
+ typedef PointOfSegment segment_point_type;
+
+ static inline void apply(PointOfSegment const& p1,
+ PointOfSegment const& p2,
+ summation& state)
+ {
+ // SUM += x2 * y1 - x1 * y2;
+ state.sum += detail::determinant<return_type>(p2, p1);
+ }
+
+ static inline return_type result(summation const& state)
+ {
+ return state.area();
+ }
+
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+ template <typename Point>
+ struct default_strategy<cartesian_tag, Point>
+ {
+ typedef strategy::area::surveyor<Point> type;
+ };
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::area
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
diff --git a/src/boost/geometry/strategies/cartesian/box_in_box.hpp b/src/boost/geometry/strategies/cartesian/box_in_box.hpp
new file mode 100644
index 0000000..7680b83
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/box_in_box.hpp
@@ -0,0 +1,176 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy
+{
+
+
+namespace within
+{
+
+struct box_within_range
+{
+ template <typename BoxContainedValue, typename BoxContainingValue>
+ static inline bool apply(BoxContainedValue const& bed_min
+ , BoxContainedValue const& bed_max
+ , BoxContainingValue const& bing_min
+ , BoxContainingValue const& bing_max)
+ {
+ return bed_min > bing_min && bed_max < bing_max;
+ }
+};
+
+
+struct box_covered_by_range
+{
+ template <typename BoxContainedValue, typename BoxContainingValue>
+ static inline bool apply(BoxContainedValue const& bed_min
+ , BoxContainedValue const& bed_max
+ , BoxContainingValue const& bing_min
+ , BoxContainingValue const& bing_max)
+ {
+ return bed_min >= bing_min && bed_max <= bing_max;
+ }
+};
+
+
+template
+<
+ typename SubStrategy,
+ typename Box1,
+ typename Box2,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct relate_box_box_loop
+{
+ static inline bool apply(Box1 const& b_contained, Box2 const& b_containing)
+ {
+ assert_dimension_equal<Box1, Box2>();
+
+ if (! SubStrategy::apply(
+ get<min_corner, Dimension>(b_contained),
+ get<max_corner, Dimension>(b_contained),
+ get<min_corner, Dimension>(b_containing),
+ get<max_corner, Dimension>(b_containing)
+ )
+ )
+ {
+ return false;
+ }
+
+ return relate_box_box_loop
+ <
+ SubStrategy,
+ Box1, Box2,
+ Dimension + 1, DimensionCount
+ >::apply(b_contained, b_containing);
+ }
+};
+
+template
+<
+ typename SubStrategy,
+ typename Box1,
+ typename Box2,
+ std::size_t DimensionCount
+>
+struct relate_box_box_loop<SubStrategy, Box1, Box2, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Box1 const& , Box2 const& )
+ {
+ return true;
+ }
+};
+
+template
+<
+ typename Box1,
+ typename Box2,
+ typename SubStrategy = box_within_range
+>
+struct box_in_box
+{
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
+ {
+ return relate_box_box_loop
+ <
+ SubStrategy,
+ Box1, Box2, 0, dimension<Box1>::type::value
+ >::apply(box1, box2);
+ }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename BoxContained, typename BoxContaining>
+struct default_strategy
+ <
+ box_tag, box_tag,
+ box_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ BoxContained, BoxContaining
+ >
+{
+ typedef within::box_in_box<BoxContained, BoxContaining> type;
+};
+
+
+}} // namespace within::services
+
+namespace covered_by { namespace services
+{
+
+template <typename BoxContained, typename BoxContaining>
+struct default_strategy
+ <
+ box_tag, box_tag,
+ box_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ BoxContained, BoxContaining
+ >
+{
+ typedef within::box_in_box
+ <
+ BoxContained, BoxContaining,
+ within::box_covered_by_range
+ > type;
+};
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
diff --git a/src/boost/geometry/strategies/cartesian/cart_intersect.hpp b/src/boost/geometry/strategies/cartesian/cart_intersect.hpp
new file mode 100644
index 0000000..ed0f500
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/cart_intersect.hpp
@@ -0,0 +1,738 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_INTERSECTION_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_INTERSECTION_HPP
+
+#include <algorithm>
+
+#include <boost/geometry/core/exception.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/geometries/concepts/segment_concept.hpp>
+
+#include <boost/geometry/arithmetic/determinant.hpp>
+#include <boost/geometry/algorithms/detail/assign_values.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+// Temporary / will be Strategy as template parameter
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+
+#include <boost/geometry/strategies/side_info.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace intersection
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <std::size_t Dimension, typename Segment, typename T>
+static inline void segment_arrange(Segment const& s, T& s_1, T& s_2, bool& swapped)
+{
+ s_1 = get<0, Dimension>(s);
+ s_2 = get<1, Dimension>(s);
+ if (s_1 > s_2)
+ {
+ std::swap(s_1, s_2);
+ swapped = true;
+ }
+}
+
+template <std::size_t Index, typename Segment>
+inline typename geometry::point_type<Segment>::type get_from_index(
+ Segment const& segment)
+{
+ typedef typename geometry::point_type<Segment>::type point_type;
+ point_type point;
+ geometry::detail::assign::assign_point_from_index
+ <
+ Segment, point_type, Index, 0, dimension<Segment>::type::value
+ >::apply(segment, point);
+ return point;
+}
+
+}
+#endif
+
+/***
+template <typename T>
+inline std::string rdebug(T const& value)
+{
+ if (math::equals(value, 0)) return "'0'";
+ if (math::equals(value, 1)) return "'1'";
+ if (value < 0) return "<0";
+ if (value > 1) return ">1";
+ return "<0..1>";
+}
+***/
+
+/*!
+ \see http://mathworld.wolfram.com/Line-LineIntersection.html
+ */
+template <typename Policy, typename CalculationType = void>
+struct relate_cartesian_segments
+{
+ typedef typename Policy::return_type return_type;
+ typedef typename Policy::segment_type1 segment_type1;
+ typedef typename Policy::segment_type2 segment_type2;
+
+ //typedef typename point_type<segment_type1>::type point_type;
+ //BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+
+ BOOST_CONCEPT_ASSERT( (concept::ConstSegment<segment_type1>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstSegment<segment_type2>) );
+
+ typedef typename select_calculation_type
+ <segment_type1, segment_type2, CalculationType>::type coordinate_type;
+
+ /// Relate segments a and b
+ static inline return_type apply(segment_type1 const& a, segment_type2 const& b)
+ {
+ coordinate_type const dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir
+ coordinate_type const dx_b = get<1, 0>(b) - get<0, 0>(b);
+ coordinate_type const dy_a = get<1, 1>(a) - get<0, 1>(a); // distance in y-dir
+ coordinate_type const dy_b = get<1, 1>(b) - get<0, 1>(b);
+ return apply(a, b, dx_a, dy_a, dx_b, dy_b);
+ }
+
+
+ // Relate segments a and b using precalculated differences.
+ // This can save two or four subtractions in many cases
+ static inline return_type apply(segment_type1 const& a, segment_type2 const& b,
+ coordinate_type const& dx_a, coordinate_type const& dy_a,
+ coordinate_type const& dx_b, coordinate_type const& dy_b)
+ {
+ typedef side::side_by_triangle<coordinate_type> side;
+ side_info sides;
+
+ bool collinear_use_first = math::abs(dx_a) + math::abs(dx_b) >= math::abs(dy_a) + math::abs(dy_b);
+
+ sides.set<0>
+ (
+ side::apply(detail::get_from_index<0>(b)
+ , detail::get_from_index<1>(b)
+ , detail::get_from_index<0>(a)),
+ side::apply(detail::get_from_index<0>(b)
+ , detail::get_from_index<1>(b)
+ , detail::get_from_index<1>(a))
+ );
+ sides.set<1>
+ (
+ side::apply(detail::get_from_index<0>(a)
+ , detail::get_from_index<1>(a)
+ , detail::get_from_index<0>(b)),
+ side::apply(detail::get_from_index<0>(a)
+ , detail::get_from_index<1>(a)
+ , detail::get_from_index<1>(b))
+ );
+
+ bool collinear = sides.collinear();
+
+ robustness_verify_collinear(a, b, sides, collinear);
+ robustness_verify_meeting(a, b, sides, collinear, collinear_use_first);
+
+ if (sides.same<0>() || sides.same<1>())
+ {
+ // Both points are at same side of other segment, we can leave
+ if (robustness_verify_same_side(a, b, sides))
+ {
+ return Policy::disjoint();
+ }
+ }
+
+ // Degenerate cases: segments of single point, lying on other segment, non disjoint
+ coordinate_type const zero = 0;
+ if (math::equals(dx_a, zero) && math::equals(dy_a, zero))
+ {
+ return Policy::degenerate(a, true);
+ }
+ if (math::equals(dx_b, zero) && math::equals(dy_b, zero))
+ {
+ return Policy::degenerate(b, false);
+ }
+
+ typedef typename select_most_precise
+ <
+ coordinate_type, double
+ >::type promoted_type;
+
+ // r: ratio 0-1 where intersection divides A/B
+ // (only calculated for non-collinear segments)
+ promoted_type r;
+ if (! collinear)
+ {
+ // Calculate determinants - Cramers rule
+ coordinate_type const wx = get<0, 0>(a) - get<0, 0>(b);
+ coordinate_type const wy = get<0, 1>(a) - get<0, 1>(b);
+ coordinate_type const d = geometry::detail::determinant<coordinate_type>(dx_a, dy_a, dx_b, dy_b);
+ coordinate_type const da = geometry::detail::determinant<coordinate_type>(dx_b, dy_b, wx, wy);
+
+ coordinate_type const zero = coordinate_type();
+ if (math::equals(d, zero))
+ {
+ // This is still a collinear case (because of FP imprecision this can occur here)
+ // sides.debug();
+ sides.set<0>(0,0);
+ sides.set<1>(0,0);
+ collinear = true;
+ }
+ else
+ {
+ r = da / d;
+
+ if (! robustness_verify_r(a, b, r))
+ {
+ return Policy::disjoint();
+ }
+
+ robustness_handle_meeting(a, b, sides, dx_a, dy_a, wx, wy, d, r);
+
+ if (robustness_verify_disjoint_at_one_collinear(a, b, sides))
+ {
+ return Policy::disjoint();
+ }
+
+ }
+ }
+
+ if(collinear)
+ {
+ if (collinear_use_first)
+ {
+ return relate_collinear<0>(a, b);
+ }
+ else
+ {
+ // Y direction contains larger segments (maybe dx is zero)
+ return relate_collinear<1>(a, b);
+ }
+ }
+
+ return Policy::segments_intersect(sides, r,
+ dx_a, dy_a, dx_b, dy_b,
+ a, b);
+ }
+
+private :
+
+
+ // Ratio should lie between 0 and 1
+ // Also these three conditions might be of FP imprecision, the segments were actually (nearly) collinear
+ template <typename T>
+ static inline bool robustness_verify_r(
+ segment_type1 const& a, segment_type2 const& b,
+ T& r)
+ {
+ T const zero = 0;
+ T const one = 1;
+ if (r < zero || r > one)
+ {
+ if (verify_disjoint<0>(a, b) || verify_disjoint<1>(a, b))
+ {
+ // Can still be disjoint (even if not one is left or right from another)
+ // This is e.g. in case #snake4 of buffer test.
+ return false;
+ }
+
+ //std::cout << "ROBUSTNESS: correction of r " << r << std::endl;
+ // sides.debug();
+
+ // ROBUSTNESS: the r value can in epsilon-cases much larger than 1, while (with perfect arithmetic)
+ // it should be one. It can be 1.14 or even 1.98049 or 2 (while still intersecting)
+
+ // If segments are crossing (we can see that with the sides)
+ // and one is inside the other, there must be an intersection point.
+ // We correct for that.
+ // This is (only) in case #ggl_list_20110820_christophe in unit tests
+
+ // If segments are touching (two sides zero), of course they should intersect
+ // This is (only) in case #buffer_rt_i in the unit tests)
+
+ // If one touches in the middle, they also should intersect (#buffer_rt_j)
+
+ // Note that even for ttmath r is occasionally > 1, e.g. 1.0000000000000000000000036191231203575
+
+ if (r > one)
+ {
+ r = one;
+ }
+ else if (r < zero)
+ {
+ r = zero;
+ }
+ }
+ return true;
+ }
+
+ static inline void robustness_verify_collinear(
+ segment_type1 const& a, segment_type2 const& b,
+ side_info& sides,
+ bool& collinear)
+ {
+ if ((sides.zero<0>() && ! sides.zero<1>()) || (sides.zero<1>() && ! sides.zero<0>()))
+ {
+ // If one of the segments is collinear, the other must be as well.
+ // So handle it as collinear.
+ // (In float/double epsilon margins it can easily occur that one or two of them are -1/1)
+ // sides.debug();
+ sides.set<0>(0,0);
+ sides.set<1>(0,0);
+ collinear = true;
+ }
+ }
+
+ static inline void robustness_verify_meeting(
+ segment_type1 const& a, segment_type2 const& b,
+ side_info& sides,
+ bool& collinear, bool& collinear_use_first)
+ {
+ if (sides.meeting())
+ {
+ // If two segments meet each other at their segment-points, two sides are zero,
+ // the other two are not (unless collinear but we don't mean those here).
+ // However, in near-epsilon ranges it can happen that two sides are zero
+ // but they do not meet at their segment-points.
+ // In that case they are nearly collinear and handled as such.
+ if (! point_equals
+ (
+ select(sides.zero_index<0>(), a),
+ select(sides.zero_index<1>(), b)
+ )
+ )
+ {
+ sides.set<0>(0,0);
+ sides.set<1>(0,0);
+ collinear = true;
+
+ if (collinear_use_first && analyse_equal<0>(a, b))
+ {
+ collinear_use_first = false;
+ }
+ else if (! collinear_use_first && analyse_equal<1>(a, b))
+ {
+ collinear_use_first = true;
+ }
+
+ }
+ }
+ }
+
+ // Verifies and if necessary correct missed touch because of robustness
+ // This is the case at multi_polygon_buffer unittest #rt_m
+ static inline bool robustness_verify_same_side(
+ segment_type1 const& a, segment_type2 const& b,
+ side_info& sides)
+ {
+ int corrected = 0;
+ if (sides.one_touching<0>())
+ {
+ if (point_equals(
+ select(sides.zero_index<0>(), a),
+ select(0, b)
+ ))
+ {
+ sides.correct_to_zero<1, 0>();
+ corrected = 1;
+ }
+ if (point_equals
+ (
+ select(sides.zero_index<0>(), a),
+ select(1, b)
+ ))
+ {
+ sides.correct_to_zero<1, 1>();
+ corrected = 2;
+ }
+ }
+ else if (sides.one_touching<1>())
+ {
+ if (point_equals(
+ select(sides.zero_index<1>(), b),
+ select(0, a)
+ ))
+ {
+ sides.correct_to_zero<0, 0>();
+ corrected = 3;
+ }
+ if (point_equals
+ (
+ select(sides.zero_index<1>(), b),
+ select(1, a)
+ ))
+ {
+ sides.correct_to_zero<0, 1>();
+ corrected = 4;
+ }
+ }
+
+ return corrected == 0;
+ }
+
+ static inline bool robustness_verify_disjoint_at_one_collinear(
+ segment_type1 const& a, segment_type2 const& b,
+ side_info const& sides)
+ {
+ if (sides.one_of_all_zero())
+ {
+ if (verify_disjoint<0>(a, b) || verify_disjoint<1>(a, b))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ // If r is one, or zero, segments should meet and their endpoints.
+ // Robustness issue: check if this is really the case.
+ // It turns out to be no problem, see buffer test #rt_s1 (and there are many cases generated)
+ // It generates an "ends in the middle" situation which is correct.
+ template <typename T, typename R>
+ static inline void robustness_handle_meeting(segment_type1 const& a, segment_type2 const& b,
+ side_info& sides,
+ T const& dx_a, T const& dy_a, T const& wx, T const& wy,
+ T const& d, R const& r)
+ {
+ return;
+
+ T const db = geometry::detail::determinant<T>(dx_a, dy_a, wx, wy);
+
+ R const zero = 0;
+ R const one = 1;
+ if (math::equals(r, zero) || math::equals(r, one))
+ {
+ R rb = db / d;
+ if (rb <= 0 || rb >= 1 || math::equals(rb, 0) || math::equals(rb, 1))
+ {
+ if (sides.one_zero<0>() && ! sides.one_zero<1>()) // or vice versa
+ {
+#if defined(BOOST_GEOMETRY_COUNT_INTERSECTION_EQUAL)
+ extern int g_count_intersection_equal;
+ g_count_intersection_equal++;
+#endif
+ sides.debug();
+ std::cout << "E r=" << r << " r.b=" << rb << " ";
+ }
+ }
+ }
+ }
+
+ template <std::size_t Dimension>
+ static inline bool verify_disjoint(segment_type1 const& a,
+ segment_type2 const& b)
+ {
+ coordinate_type a_1, a_2, b_1, b_2;
+ bool a_swapped = false, b_swapped = false;
+ detail::segment_arrange<Dimension>(a, a_1, a_2, a_swapped);
+ detail::segment_arrange<Dimension>(b, b_1, b_2, b_swapped);
+ return math::smaller(a_2, b_1) || math::larger(a_1, b_2);
+ }
+
+ template <typename Segment>
+ static inline typename point_type<Segment>::type select(int index, Segment const& segment)
+ {
+ return index == 0
+ ? detail::get_from_index<0>(segment)
+ : detail::get_from_index<1>(segment)
+ ;
+ }
+
+ // We cannot use geometry::equals here. Besides that this will be changed
+ // to compare segment-coordinate-values directly (not necessary to retrieve point first)
+ template <typename Point1, typename Point2>
+ static inline bool point_equals(Point1 const& point1, Point2 const& point2)
+ {
+ return math::equals(get<0>(point1), get<0>(point2))
+ && math::equals(get<1>(point1), get<1>(point2))
+ ;
+ }
+
+ // We cannot use geometry::equals here. Besides that this will be changed
+ // to compare segment-coordinate-values directly (not necessary to retrieve point first)
+ template <typename Point1, typename Point2>
+ static inline bool point_equality(Point1 const& point1, Point2 const& point2,
+ bool& equals_0, bool& equals_1)
+ {
+ equals_0 = math::equals(get<0>(point1), get<0>(point2));
+ equals_1 = math::equals(get<1>(point1), get<1>(point2));
+ return equals_0 && equals_1;
+ }
+
+ template <std::size_t Dimension>
+ static inline bool analyse_equal(segment_type1 const& a, segment_type2 const& b)
+ {
+ coordinate_type const a_1 = geometry::get<0, Dimension>(a);
+ coordinate_type const a_2 = geometry::get<1, Dimension>(a);
+ coordinate_type const b_1 = geometry::get<0, Dimension>(b);
+ coordinate_type const b_2 = geometry::get<1, Dimension>(b);
+ return math::equals(a_1, b_1)
+ || math::equals(a_2, b_1)
+ || math::equals(a_1, b_2)
+ || math::equals(a_2, b_2)
+ ;
+ }
+
+ template <std::size_t Dimension>
+ static inline return_type relate_collinear(segment_type1 const& a,
+ segment_type2 const& b)
+ {
+ coordinate_type a_1, a_2, b_1, b_2;
+ bool a_swapped = false, b_swapped = false;
+ detail::segment_arrange<Dimension>(a, a_1, a_2, a_swapped);
+ detail::segment_arrange<Dimension>(b, b_1, b_2, b_swapped);
+ if (math::smaller(a_2, b_1) || math::larger(a_1, b_2))
+ //if (a_2 < b_1 || a_1 > b_2)
+ {
+ return Policy::disjoint();
+ }
+ return relate_collinear(a, b, a_1, a_2, b_1, b_2, a_swapped, b_swapped);
+ }
+
+ /// Relate segments known collinear
+ static inline return_type relate_collinear(segment_type1 const& a
+ , segment_type2 const& b
+ , coordinate_type a_1, coordinate_type a_2
+ , coordinate_type b_1, coordinate_type b_2
+ , bool a_swapped, bool b_swapped)
+ {
+ // All ca. 150 lines are about collinear rays
+ // The intersections, if any, are always boundary points of the segments. No need to calculate anything.
+ // However we want to find out HOW they intersect, there are many cases.
+ // Most sources only provide the intersection (above) or that there is a collinearity (but not the points)
+ // or some spare sources give the intersection points (calculated) but not how they align.
+ // This source tries to give everything and still be efficient.
+ // It is therefore (and because of the extensive clarification comments) rather long...
+
+ // \see http://mpa.itc.it/radim/g50history/CMP/4.2.1-CERL-beta-libes/file475.txt
+ // \see http://docs.codehaus.org/display/GEOTDOC/Point+Set+Theory+and+the+DE-9IM+Matrix
+ // \see http://mathworld.wolfram.com/Line-LineIntersection.html
+
+ // Because of collinearity the case is now one-dimensional and can be checked using intervals
+ // This function is called either horizontally or vertically
+ // We get then two intervals:
+ // a_1-------------a_2 where a_1 < a_2
+ // b_1-------------b_2 where b_1 < b_2
+ // In all figures below a_1/a_2 denotes arranged intervals, a1-a2 or a2-a1 are still unarranged
+
+ // Handle "equal", in polygon neighbourhood comparisons a common case
+
+ bool const opposite = a_swapped ^ b_swapped;
+ bool const both_swapped = a_swapped && b_swapped;
+
+ // Check if segments are equal or opposite equal...
+ bool const swapped_a1_eq_b1 = math::equals(a_1, b_1);
+ bool const swapped_a2_eq_b2 = math::equals(a_2, b_2);
+
+ if (swapped_a1_eq_b1 && swapped_a2_eq_b2)
+ {
+ return Policy::segment_equal(a, opposite);
+ }
+
+ bool const swapped_a2_eq_b1 = math::equals(a_2, b_1);
+ bool const swapped_a1_eq_b2 = math::equals(a_1, b_2);
+
+ bool const a1_eq_b1 = both_swapped ? swapped_a2_eq_b2 : a_swapped ? swapped_a2_eq_b1 : b_swapped ? swapped_a1_eq_b2 : swapped_a1_eq_b1;
+ bool const a2_eq_b2 = both_swapped ? swapped_a1_eq_b1 : a_swapped ? swapped_a1_eq_b2 : b_swapped ? swapped_a2_eq_b1 : swapped_a2_eq_b2;
+
+ bool const a1_eq_b2 = both_swapped ? swapped_a2_eq_b1 : a_swapped ? swapped_a2_eq_b2 : b_swapped ? swapped_a1_eq_b1 : swapped_a1_eq_b2;
+ bool const a2_eq_b1 = both_swapped ? swapped_a1_eq_b2 : a_swapped ? swapped_a1_eq_b1 : b_swapped ? swapped_a2_eq_b2 : swapped_a2_eq_b1;
+
+
+
+
+ // The rest below will return one or two intersections.
+ // The delegated class can decide which is the intersection point, or two, build the Intersection Matrix (IM)
+ // For IM it is important to know which relates to which. So this information is given,
+ // without performance penalties to intersection calculation
+
+ bool const has_common_points = swapped_a1_eq_b1 || swapped_a1_eq_b2 || swapped_a2_eq_b1 || swapped_a2_eq_b2;
+
+
+ // "Touch" -> one intersection point -> one but not two common points
+ // --------> A (or B)
+ // <---------- B (or A)
+ // a_2==b_1 (b_2==a_1 or a_2==b1)
+
+ // The check a_2/b_1 is necessary because it excludes cases like
+ // ------->
+ // --->
+ // ... which are handled lateron
+
+ // Corresponds to 4 cases, of which the equal points are determined above
+ // #1: a1---->a2 b1--->b2 (a arrives at b's border)
+ // #2: a2<----a1 b2<---b1 (b arrives at a's border)
+ // #3: a1---->a2 b2<---b1 (both arrive at each others border)
+ // #4: a2<----a1 b1--->b2 (no arrival at all)
+ // Where the arranged forms have two forms:
+ // a_1-----a_2/b_1-------b_2 or reverse (B left of A)
+ if ((swapped_a2_eq_b1 || swapped_a1_eq_b2) && ! swapped_a1_eq_b1 && ! swapped_a2_eq_b2)
+ {
+ if (a2_eq_b1) return Policy::collinear_touch(get<1, 0>(a), get<1, 1>(a), 0, -1);
+ if (a1_eq_b2) return Policy::collinear_touch(get<0, 0>(a), get<0, 1>(a), -1, 0);
+ if (a2_eq_b2) return Policy::collinear_touch(get<1, 0>(a), get<1, 1>(a), 0, 0);
+ if (a1_eq_b1) return Policy::collinear_touch(get<0, 0>(a), get<0, 1>(a), -1, -1);
+ }
+
+
+ // "Touch/within" -> there are common points and also an intersection of interiors:
+ // Corresponds to many cases:
+ // #1a: a1------->a2 #1b: a1-->a2
+ // b1--->b2 b1------->b2
+ // #2a: a2<-------a1 #2b: a2<--a1
+ // b1--->b2 b1------->b2
+ // #3a: a1------->a2 #3b: a1-->a2
+ // b2<---b1 b2<-------b1
+ // #4a: a2<-------a1 #4b: a2<--a1
+ // b2<---b1 b2<-------b1
+
+ // Note: next cases are similar and handled by the code
+ // #4c: a1--->a2
+ // b1-------->b2
+ // #4d: a1-------->a2
+ // b1-->b2
+
+ // For case 1-4: a_1 < (b_1 or b_2) < a_2, two intersections are equal to segment B
+ // For case 5-8: b_1 < (a_1 or a_2) < b_2, two intersections are equal to segment A
+ if (has_common_points)
+ {
+ // Either A is in B, or B is in A, or (in case of robustness/equals)
+ // both are true, see below
+ bool a_in_b = (b_1 < a_1 && a_1 < b_2) || (b_1 < a_2 && a_2 < b_2);
+ bool b_in_a = (a_1 < b_1 && b_1 < a_2) || (a_1 < b_2 && b_2 < a_2);
+
+ if (a_in_b && b_in_a)
+ {
+ // testcase "ggl_list_20110306_javier"
+ // In robustness it can occur that a point of A is inside B AND a point of B is inside A,
+ // still while has_common_points is true (so one point equals the other).
+ // If that is the case we select on length.
+ coordinate_type const length_a = geometry::math::abs(a_1 - a_2);
+ coordinate_type const length_b = geometry::math::abs(b_1 - b_2);
+ if (length_a > length_b)
+ {
+ a_in_b = false;
+ }
+ else
+ {
+ b_in_a = false;
+ }
+ }
+
+ int const arrival_a = a_in_b ? 1 : -1;
+ if (a2_eq_b2) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, 0, 0, false);
+ if (a1_eq_b2) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, arrival_a, 0, true);
+ if (a2_eq_b1) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, 0, -arrival_a, true);
+ if (a1_eq_b1) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, arrival_a, -arrival_a, false);
+ }
+
+
+
+ // "Inside", a completely within b or b completely within a
+ // 2 cases:
+ // case 1:
+ // a_1---a_2 -> take A's points as intersection points
+ // b_1------------b_2
+ // case 2:
+ // a_1------------a_2
+ // b_1---b_2 -> take B's points
+ if (a_1 > b_1 && a_2 < b_2)
+ {
+ // A within B
+ return Policy::collinear_a_in_b(a, opposite);
+ }
+ if (b_1 > a_1 && b_2 < a_2)
+ {
+ // B within A
+ return Policy::collinear_b_in_a(b, opposite);
+ }
+
+
+ /*
+
+ Now that all cases with equal,touch,inside,disjoint,
+ degenerate are handled the only thing left is an overlap
+
+ Either a1 is between b1,b2
+ or a2 is between b1,b2 (a2 arrives)
+
+ Next table gives an overview.
+ The IP's are ordered following the line A1->A2
+
+ | |
+ | a_2 in between | a_1 in between
+ | |
+ -----+---------------------------------+--------------------------
+ | a1--------->a2 | a1--------->a2
+ | b1----->b2 | b1----->b2
+ | (b1,a2), a arrives | (a1,b2), b arrives
+ | |
+ -----+---------------------------------+--------------------------
+ a sw.| a2<---------a1* | a2<---------a1*
+ | b1----->b2 | b1----->b2
+ | (a1,b1), no arrival | (b2,a2), a and b arrive
+ | |
+ -----+---------------------------------+--------------------------
+ | a1--------->a2 | a1--------->a2
+ b sw.| b2<-----b1 | b2<-----b1
+ | (b2,a2), a and b arrive | (a1,b1), no arrival
+ | |
+ -----+---------------------------------+--------------------------
+ a sw.| a2<---------a1* | a2<---------a1*
+ b sw.| b2<-----b1 | b2<-----b1
+ | (a1,b2), b arrives | (b1,a2), a arrives
+ | |
+ -----+---------------------------------+--------------------------
+ * Note that a_1 < a_2, and a1 <> a_1; if a is swapped,
+ the picture might seem wrong but it (supposed to be) is right.
+ */
+
+ if (b_1 < a_2 && a_2 < b_2)
+ {
+ // Left column, from bottom to top
+ return
+ both_swapped ? Policy::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<1, 0>(b), get<1, 1>(b), -1, 1, opposite)
+ : b_swapped ? Policy::collinear_overlaps(get<1, 0>(b), get<1, 1>(b), get<1, 0>(a), get<1, 1>(a), 1, 1, opposite)
+ : a_swapped ? Policy::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<0, 0>(b), get<0, 1>(b), -1, -1, opposite)
+ : Policy::collinear_overlaps(get<0, 0>(b), get<0, 1>(b), get<1, 0>(a), get<1, 1>(a), 1, -1, opposite)
+ ;
+ }
+ if (b_1 < a_1 && a_1 < b_2)
+ {
+ // Right column, from bottom to top
+ return
+ both_swapped ? Policy::collinear_overlaps(get<0, 0>(b), get<0, 1>(b), get<1, 0>(a), get<1, 1>(a), 1, -1, opposite)
+ : b_swapped ? Policy::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<0, 0>(b), get<0, 1>(b), -1, -1, opposite)
+ : a_swapped ? Policy::collinear_overlaps(get<1, 0>(b), get<1, 1>(b), get<1, 0>(a), get<1, 1>(a), 1, 1, opposite)
+ : Policy::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<1, 0>(b), get<1, 1>(b), -1, 1, opposite)
+ ;
+ }
+ // Nothing should goes through. If any we have made an error
+ // std::cout << "Robustness issue, non-logical behaviour" << std::endl;
+ return Policy::error("Robustness issue, non-logical behaviour");
+ }
+};
+
+
+}} // namespace strategy::intersection
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_INTERSECTION_HPP
diff --git a/src/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp b/src/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
new file mode 100644
index 0000000..8b42715
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
@@ -0,0 +1,242 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/arithmetic/determinant.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/strategies/centroid.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+// Note: when calling the namespace "centroid", it sometimes,
+// somehow, in gcc, gives compilation problems (confusion with function centroid).
+
+namespace strategy { namespace centroid
+{
+
+
+
+/*!
+\brief Centroid calculation using algorith Bashein / Detmer
+\ingroup strategies
+\details Calculates centroid using triangulation method published by
+ Bashein / Detmer
+\tparam Point point type of centroid to calculate
+\tparam PointOfSegment point type of segments, defaults to Point
+\par Concepts for Point and PointOfSegment:
+- specialized point_traits class
+\author Adapted from "Centroid of a Polygon" by
+ Gerard Bashein and Paul R. Detmer<em>,
+in "Graphics Gems IV", Academic Press, 1994</em>
+\par Research notes
+The algorithm gives the same results as Oracle and PostGIS but
+ differs from MySQL
+(tried 5.0.21 / 5.0.45 / 5.0.51a / 5.1.23).
+
+Without holes:
+- this: POINT(4.06923363095238 1.65055803571429)
+- geolib: POINT(4.07254 1.66819)
+- MySQL: POINT(3.6636363636364 1.6272727272727)'
+- PostGIS: POINT(4.06923363095238 1.65055803571429)
+- Oracle: 4.06923363095238 1.65055803571429
+- SQL Server: POINT(4.06923362245959 1.65055804168294)
+
+Statements:
+- \b MySQL/PostGIS: select AsText(Centroid(GeomFromText(
+ 'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6
+ ,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))')))
+- \b Oracle: select sdo_geom.sdo_centroid(sdo_geometry(2003, null, null,
+ sdo_elem_info_array(1, 1003, 1), sdo_ordinate_array(
+ 2,1.3,2.4,1.7,2.8,1.8,3.4,1.2,3.7,1.6,3.4,2,4.1,3,5.3,2.6
+ ,5.4,1.2,4.9,0.8,2.9,0.7,2,1.3))
+ , mdsys.sdo_dim_array(mdsys.sdo_dim_element('x',0,10,.00000005)
+ ,mdsys.sdo_dim_element('y',0,10,.00000005)))
+ from dual
+- \b SQL Server 2008: select geometry::STGeomFromText(
+ 'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6
+ ,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))',0)
+ .STCentroid()
+ .STAsText()
+
+With holes:
+- this: POINT(4.04663 1.6349)
+- geolib: POINT(4.04675 1.65735)
+- MySQL: POINT(3.6090580503834 1.607573932092)
+- PostGIS: POINT(4.0466265060241 1.63489959839357)
+- Oracle: 4.0466265060241 1.63489959839357
+- SQL Server: POINT(4.0466264962959677 1.6348996057331333)
+
+Statements:
+- \b MySQL/PostGIS: select AsText(Centroid(GeomFromText(
+ 'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2
+ ,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3)
+ ,(4 2,4.2 1.4,4.8 1.9,4.4 2.2,4 2))')));
+- \b Oracle: select sdo_geom.sdo_centroid(sdo_geometry(2003, null, null
+ , sdo_elem_info_array(1, 1003, 1, 25, 2003, 1)
+ , sdo_ordinate_array(2,1.3,2.4,1.7,2.8,1.8,3.4,1.2,3.7,1.6,3.4,
+ 2,4.1,3,5.3,2.6,5.4,1.2,4.9,0.8,2.9,0.7,2,1.3,4,2, 4.2,1.4,
+ 4.8,1.9, 4.4,2.2, 4,2))
+ , mdsys.sdo_dim_array(mdsys.sdo_dim_element('x',0,10,.00000005)
+ ,mdsys.sdo_dim_element('y',0,10,.00000005)))
+ from dual
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.centroid.centroid_3_with_strategy centroid (with strategy)]
+}
+
+ */
+template
+<
+ typename Point,
+ typename PointOfSegment = Point,
+ typename CalculationType = void
+>
+class bashein_detmer
+{
+private :
+ // If user specified a calculation type, use that type,
+ // whatever it is and whatever the point-type(s) are.
+ // Else, use the most appropriate coordinate type
+ // of the two points, but at least double
+ typedef typename
+ boost::mpl::if_c
+ <
+ boost::is_void<CalculationType>::type::value,
+ typename select_most_precise
+ <
+ typename select_coordinate_type
+ <
+ Point,
+ PointOfSegment
+ >::type,
+ double
+ >::type,
+ CalculationType
+ >::type calculation_type;
+
+ /*! subclass to keep state */
+ class sums
+ {
+ friend class bashein_detmer;
+ int count;
+ calculation_type sum_a2;
+ calculation_type sum_x;
+ calculation_type sum_y;
+
+ public :
+ inline sums()
+ : count(0)
+ , sum_a2(calculation_type())
+ , sum_x(calculation_type())
+ , sum_y(calculation_type())
+ {
+ typedef calculation_type ct;
+ }
+ };
+
+public :
+ typedef sums state_type;
+
+ static inline void apply(PointOfSegment const& p1,
+ PointOfSegment const& p2, sums& state)
+ {
+ /* Algorithm:
+ For each segment:
+ begin
+ ai = x1 * y2 - x2 * y1;
+ sum_a2 += ai;
+ sum_x += ai * (x1 + x2);
+ sum_y += ai * (y1 + y2);
+ end
+ return POINT(sum_x / (3 * sum_a2), sum_y / (3 * sum_a2) )
+ */
+
+ // Get coordinates and promote them to calculation_type
+ calculation_type const x1 = boost::numeric_cast<calculation_type>(get<0>(p1));
+ calculation_type const y1 = boost::numeric_cast<calculation_type>(get<1>(p1));
+ calculation_type const x2 = boost::numeric_cast<calculation_type>(get<0>(p2));
+ calculation_type const y2 = boost::numeric_cast<calculation_type>(get<1>(p2));
+ calculation_type const ai = geometry::detail::determinant<calculation_type>(p1, p2);
+ state.count++;
+ state.sum_a2 += ai;
+ state.sum_x += ai * (x1 + x2);
+ state.sum_y += ai * (y1 + y2);
+ }
+
+ static inline bool result(sums const& state, Point& centroid)
+ {
+ calculation_type const zero = calculation_type();
+ if (state.count > 0 && ! math::equals(state.sum_a2, zero))
+ {
+ calculation_type const v3 = 3;
+ calculation_type const a3 = v3 * state.sum_a2;
+
+ typedef typename geometry::coordinate_type
+ <
+ Point
+ >::type coordinate_type;
+
+ set<0>(centroid,
+ boost::numeric_cast<coordinate_type>(state.sum_x / a3));
+ set<1>(centroid,
+ boost::numeric_cast<coordinate_type>(state.sum_y / a3));
+ return true;
+ }
+
+ return false;
+ }
+
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+// Register this strategy for rings and (multi)polygons, in two dimensions
+template <typename Point, typename Geometry>
+struct default_strategy<cartesian_tag, areal_tag, 2, Point, Geometry>
+{
+ typedef bashein_detmer
+ <
+ Point,
+ typename point_type<Geometry>::type
+ > type;
+};
+
+
+} // namespace services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::centroid
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
diff --git a/src/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp b/src/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
new file mode 100644
index 0000000..48feae5
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
@@ -0,0 +1,144 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
+
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+#include <boost/geometry/strategies/centroid.hpp>
+#include <boost/geometry/strategies/default_distance_result.hpp>
+
+// Helper geometry
+#include <boost/geometry/geometries/point.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace centroid
+{
+
+namespace detail
+{
+
+template <typename Type, std::size_t DimensionCount>
+struct weighted_length_sums
+{
+ typedef typename geometry::model::point
+ <
+ Type, DimensionCount,
+ cs::cartesian
+ > work_point;
+
+ Type length;
+ work_point average_sum;
+
+ inline weighted_length_sums()
+ : length(Type())
+ {
+ geometry::assign_zero(average_sum);
+ }
+};
+}
+
+template
+<
+ typename Point,
+ typename PointOfSegment = Point
+>
+class weighted_length
+{
+private :
+ typedef typename select_most_precise
+ <
+ typename default_distance_result<Point>::type,
+ typename default_distance_result<PointOfSegment>::type
+ >::type distance_type;
+
+public :
+ typedef detail::weighted_length_sums
+ <
+ distance_type,
+ geometry::dimension<Point>::type::value
+ > state_type;
+
+ static inline void apply(PointOfSegment const& p1,
+ PointOfSegment const& p2, state_type& state)
+ {
+ distance_type const d = geometry::distance(p1, p2);
+ state.length += d;
+
+ typename state_type::work_point weighted_median;
+ geometry::assign_zero(weighted_median);
+ geometry::add_point(weighted_median, p1);
+ geometry::add_point(weighted_median, p2);
+ geometry::multiply_value(weighted_median, d/2);
+ geometry::add_point(state.average_sum, weighted_median);
+ }
+
+ static inline bool result(state_type const& state, Point& centroid)
+ {
+ distance_type const zero = distance_type();
+ if (! geometry::math::equals(state.length, zero))
+ {
+ assign_zero(centroid);
+ add_point(centroid, state.average_sum);
+ divide_value(centroid, state.length);
+ return true;
+ }
+
+ return false;
+ }
+
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+
+// Register this strategy for linear geometries, in all dimensions
+
+template <std::size_t N, typename Point, typename Geometry>
+struct default_strategy
+<
+ cartesian_tag,
+ linear_tag,
+ N,
+ Point,
+ Geometry
+>
+{
+ typedef weighted_length
+ <
+ Point,
+ typename point_type<Geometry>::type
+ > type;
+};
+
+
+} // namespace services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::centroid
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
diff --git a/src/boost/geometry/strategies/cartesian/distance_projected_point.hpp b/src/boost/geometry/strategies/cartesian/distance_projected_point.hpp
new file mode 100644
index 0000000..13d4168
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/distance_projected_point.hpp
@@ -0,0 +1,319 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/point_type.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/arithmetic/dot_product.hpp>
+
+#include <boost/geometry/strategies/tags.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/default_distance_result.hpp>
+#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+// Helper geometry (projected point on line)
+#include <boost/geometry/geometries/point.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace distance
+{
+
+
+/*!
+\brief Strategy for distance point to segment
+\ingroup strategies
+\details Calculates distance using projected-point method, and (optionally) Pythagoras
+\author Adapted from: http://geometryalgorithms.com/Archive/algorithm_0102/algorithm_0102.htm
+\tparam Point \tparam_point
+\tparam PointOfSegment \tparam_segment_point
+\tparam CalculationType \tparam_calculation
+\tparam Strategy underlying point-point distance strategy
+\par Concepts for Strategy:
+- cartesian_distance operator(Point,Point)
+\note If the Strategy is a "comparable::pythagoras", this strategy
+ automatically is a comparable projected_point strategy (so without sqrt)
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
+}
+
+*/
+template
+<
+ typename Point,
+ typename PointOfSegment = Point,
+ typename CalculationType = void,
+ typename Strategy = pythagoras<Point, PointOfSegment, CalculationType>
+>
+class projected_point
+{
+public :
+ // The three typedefs below are necessary to calculate distances
+ // from segments defined in integer coordinates.
+
+ // Integer coordinates can still result in FP distances.
+ // There is a division, which must be represented in FP.
+ // So promote.
+ typedef typename promote_floating_point
+ <
+ typename strategy::distance::services::return_type
+ <
+ Strategy
+ >::type
+ >::type calculation_type;
+
+private :
+
+ // A projected point of points in Integer coordinates must be able to be
+ // represented in FP.
+ typedef model::point
+ <
+ calculation_type,
+ dimension<PointOfSegment>::value,
+ typename coordinate_system<PointOfSegment>::type
+ > fp_point_type;
+
+ // For convenience
+ typedef fp_point_type fp_vector_type;
+
+ // We have to use a strategy using FP coordinates (fp-type) which is
+ // not always the same as Strategy (defined as point_strategy_type)
+ // So we create a "similar" one
+ typedef typename strategy::distance::services::similar_type
+ <
+ Strategy,
+ Point,
+ fp_point_type
+ >::type fp_strategy_type;
+
+public :
+
+ inline calculation_type apply(Point const& p,
+ PointOfSegment const& p1, PointOfSegment const& p2) const
+ {
+ assert_dimension_equal<Point, PointOfSegment>();
+
+ /*
+ Algorithm [p1: (x1,y1), p2: (x2,y2), p: (px,py)]
+ VECTOR v(x2 - x1, y2 - y1)
+ VECTOR w(px - x1, py - y1)
+ c1 = w . v
+ c2 = v . v
+ b = c1 / c2
+ RETURN POINT(x1 + b * vx, y1 + b * vy)
+ */
+
+ // v is multiplied below with a (possibly) FP-value, so should be in FP
+ // For consistency we define w also in FP
+ fp_vector_type v, w;
+
+ geometry::convert(p2, v);
+ geometry::convert(p, w);
+ subtract_point(v, p1);
+ subtract_point(w, p1);
+
+ Strategy strategy;
+ boost::ignore_unused_variable_warning(strategy);
+
+ calculation_type const zero = calculation_type();
+ calculation_type const c1 = dot_product(w, v);
+ if (c1 <= zero)
+ {
+ return strategy.apply(p, p1);
+ }
+ calculation_type const c2 = dot_product(v, v);
+ if (c2 <= c1)
+ {
+ return strategy.apply(p, p2);
+ }
+
+ // See above, c1 > 0 AND c2 > c1 so: c2 != 0
+ calculation_type const b = c1 / c2;
+
+ fp_strategy_type fp_strategy
+ = strategy::distance::services::get_similar
+ <
+ Strategy, Point, fp_point_type
+ >::apply(strategy);
+
+ fp_point_type projected;
+ geometry::convert(p1, projected);
+ multiply_value(v, b);
+ add_point(projected, v);
+
+ //std::cout << "distance " << dsv(p) << " .. " << dsv(projected) << std::endl;
+
+ return fp_strategy.apply(p, projected);
+ }
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct tag<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef strategy_tag_distance_point_segment type;
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct return_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef typename projected_point<Point, PointOfSegment, CalculationType, Strategy>::calculation_type type;
+};
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct strategy_point_point<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef Strategy type;
+};
+
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy,
+ typename P1,
+ typename P2
+>
+struct similar_type<projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2>
+{
+ typedef projected_point<P1, P2, CalculationType, Strategy> type;
+};
+
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy,
+ typename P1,
+ typename P2
+>
+struct get_similar<projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2>
+{
+ static inline typename similar_type
+ <
+ projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2
+ >::type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& )
+ {
+ return projected_point<P1, P2, CalculationType, Strategy>();
+ }
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct comparable_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ // Define a projected_point strategy with its underlying point-point-strategy
+ // being comparable
+ typedef projected_point
+ <
+ Point,
+ PointOfSegment,
+ CalculationType,
+ typename comparable_type<Strategy>::type
+ > type;
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct get_comparable<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef typename comparable_type
+ <
+ projected_point<Point, PointOfSegment, CalculationType, Strategy>
+ >::type comparable_type;
+public :
+ static inline comparable_type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& )
+ {
+ return comparable_type();
+ }
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct result_from_distance<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+private :
+ typedef typename return_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >::type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& , T const& value)
+ {
+ Strategy s;
+ return result_from_distance<Strategy>::apply(s, value);
+ }
+};
+
+
+// Get default-strategy for point-segment distance calculation
+// while still have the possibility to specify point-point distance strategy (PPS)
+// It is used in algorithms/distance.hpp where users specify PPS for distance
+// of point-to-segment or point-to-linestring.
+// Convenient for geographic coordinate systems especially.
+template <typename Point, typename PointOfSegment, typename Strategy>
+struct default_strategy<segment_tag, Point, PointOfSegment, cartesian_tag, cartesian_tag, Strategy>
+{
+ typedef strategy::distance::projected_point
+ <
+ Point,
+ PointOfSegment,
+ void,
+ typename boost::mpl::if_
+ <
+ boost::is_void<Strategy>,
+ typename default_strategy
+ <
+ point_tag, Point, PointOfSegment,
+ cartesian_tag, cartesian_tag
+ >::type,
+ Strategy
+ >::type
+ > type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
diff --git a/src/boost/geometry/strategies/cartesian/distance_pythagoras.hpp b/src/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
new file mode 100644
index 0000000..51d2722
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
@@ -0,0 +1,349 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/access.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+#include <boost/geometry/util/calculation_type.hpp>
+
+
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Point1, typename Point2, size_t I, typename T>
+struct compute_pythagoras
+{
+ static inline T apply(Point1 const& p1, Point2 const& p2)
+ {
+ T const c1 = boost::numeric_cast<T>(get<I-1>(p2));
+ T const c2 = boost::numeric_cast<T>(get<I-1>(p1));
+ T const d = c1 - c2;
+ return d * d + compute_pythagoras<Point1, Point2, I-1, T>::apply(p1, p2);
+ }
+};
+
+template <typename Point1, typename Point2, typename T>
+struct compute_pythagoras<Point1, Point2, 0, T>
+{
+ static inline T apply(Point1 const&, Point2 const&)
+ {
+ return boost::numeric_cast<T>(0);
+ }
+};
+
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+namespace comparable
+{
+
+/*!
+\brief Strategy to calculate comparable distance between two points
+\ingroup strategies
+\tparam Point1 \tparam_first_point
+\tparam Point2 \tparam_second_point
+\tparam CalculationType \tparam_calculation
+*/
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
+class pythagoras
+{
+public :
+
+ typedef typename util::calculation_type::geometric::binary
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type calculation_type;
+
+ static inline calculation_type apply(Point1 const& p1, Point2 const& p2)
+ {
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point1>) );
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+ // Calculate distance using Pythagoras
+ // (Leave comment above for Doxygen)
+
+ assert_dimension_equal<Point1, Point2>();
+
+ return detail::compute_pythagoras
+ <
+ Point1, Point2,
+ dimension<Point1>::value,
+ calculation_type
+ >::apply(p1, p2);
+ }
+};
+
+} // namespace comparable
+
+
+/*!
+\brief Strategy to calculate the distance between two points
+\ingroup strategies
+\tparam Point1 \tparam_first_point
+\tparam Point2 \tparam_second_point
+\tparam CalculationType \tparam_calculation
+
+\qbk{
+[heading Notes]
+[note Can be used for points with two\, three or more dimensions]
+[heading See also]
+[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
+}
+
+*/
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
+class pythagoras
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
+public :
+ typedef typename util::calculation_type::geometric::binary
+ <
+ Point1,
+ Point2,
+ CalculationType,
+ double,
+ double // promote integer to double
+ >::type calculation_type;
+
+ /*!
+ \brief applies the distance calculation using pythagoras
+ \return the calculated distance (including taking the square root)
+ \param p1 first point
+ \param p2 second point
+ */
+ static inline calculation_type apply(Point1 const& p1, Point2 const& p2)
+ {
+ calculation_type const t = comparable_type::apply(p1, p2);
+ return sqrt(t);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct tag<pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct return_type<pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef typename pythagoras<Point1, Point2, CalculationType>::calculation_type type;
+};
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename CalculationType,
+ typename P1,
+ typename P2
+>
+struct similar_type<pythagoras<Point1, Point2, CalculationType>, P1, P2>
+{
+ typedef pythagoras<P1, P2, CalculationType> type;
+};
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename CalculationType,
+ typename P1,
+ typename P2
+>
+struct get_similar<pythagoras<Point1, Point2, CalculationType>, P1, P2>
+{
+ static inline typename similar_type
+ <
+ pythagoras<Point1, Point2, CalculationType>, P1, P2
+ >::type apply(pythagoras<Point1, Point2, CalculationType> const& )
+ {
+ return pythagoras<P1, P2, CalculationType>();
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct comparable_type<pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct get_comparable<pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
+public :
+ static inline comparable_type apply(pythagoras<Point1, Point2, CalculationType> const& )
+ {
+ return comparable_type();
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct result_from_distance<pythagoras<Point1, Point2, CalculationType> >
+{
+private :
+ typedef typename return_type<pythagoras<Point1, Point2, CalculationType> >::type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(pythagoras<Point1, Point2, CalculationType> const& , T const& value)
+ {
+ return return_type(value);
+ }
+};
+
+
+// Specializations for comparable::pythagoras
+template <typename Point1, typename Point2, typename CalculationType>
+struct tag<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct return_type<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef typename comparable::pythagoras<Point1, Point2, CalculationType>::calculation_type type;
+};
+
+
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename CalculationType,
+ typename P1,
+ typename P2
+>
+struct similar_type<comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2>
+{
+ typedef comparable::pythagoras<P1, P2, CalculationType> type;
+};
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename CalculationType,
+ typename P1,
+ typename P2
+>
+struct get_similar<comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2>
+{
+ static inline typename similar_type
+ <
+ comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2
+ >::type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& )
+ {
+ return comparable::pythagoras<P1, P2, CalculationType>();
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct comparable_type<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct get_comparable<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
+public :
+ static inline comparable_type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& )
+ {
+ return comparable_type();
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct result_from_distance<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+private :
+ typedef typename return_type<comparable::pythagoras<Point1, Point2, CalculationType> >::type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& , T const& value)
+ {
+ return_type const v = value;
+ return v * v;
+ }
+};
+
+
+template <typename Point1, typename Point2>
+struct default_strategy<point_tag, Point1, Point2, cartesian_tag, cartesian_tag, void>
+{
+ typedef pythagoras<Point1, Point2> type;
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
diff --git a/src/boost/geometry/strategies/cartesian/point_in_box.hpp b/src/boost/geometry/strategies/cartesian/point_in_box.hpp
new file mode 100644
index 0000000..275f755
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/point_in_box.hpp
@@ -0,0 +1,172 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy
+{
+
+namespace within
+{
+
+
+struct within_range
+{
+ template <typename Value1, typename Value2>
+ static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
+ {
+ return value > min_value && value < max_value;
+ }
+};
+
+
+struct covered_by_range
+{
+ template <typename Value1, typename Value2>
+ static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
+ {
+ return value >= min_value && value <= max_value;
+ }
+};
+
+
+template
+<
+ typename SubStrategy,
+ typename Point,
+ typename Box,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct relate_point_box_loop
+{
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ if (! SubStrategy::apply(get<Dimension>(point),
+ get<min_corner, Dimension>(box),
+ get<max_corner, Dimension>(box))
+ )
+ {
+ return false;
+ }
+
+ return relate_point_box_loop
+ <
+ SubStrategy,
+ Point, Box,
+ Dimension + 1, DimensionCount
+ >::apply(point, box);
+ }
+};
+
+
+template
+<
+ typename SubStrategy,
+ typename Point,
+ typename Box,
+ std::size_t DimensionCount
+>
+struct relate_point_box_loop<SubStrategy, Point, Box, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Point const& , Box const& )
+ {
+ return true;
+ }
+};
+
+
+template
+<
+ typename Point,
+ typename Box,
+ typename SubStrategy = within_range
+>
+struct point_in_box
+{
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ return relate_point_box_loop
+ <
+ SubStrategy,
+ Point, Box,
+ 0, dimension<Point>::type::value
+ >::apply(point, box);
+ }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag,
+ point_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ Point, Box
+ >
+{
+ typedef within::point_in_box<Point, Box> type;
+};
+
+
+}} // namespace within::services
+
+
+namespace covered_by { namespace services
+{
+
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag,
+ point_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ Point, Box
+ >
+{
+ typedef within::point_in_box
+ <
+ Point, Box,
+ within::covered_by_range
+ > type;
+};
+
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
diff --git a/src/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp b/src/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp
new file mode 100644
index 0000000..94da5cc
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp
@@ -0,0 +1,124 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace within
+{
+
+/*!
+\brief Within detection using cross counting,
+\ingroup strategies
+\tparam Point \tparam_point
+\tparam PointOfSegment \tparam_segment_point
+\tparam CalculationType \tparam_calculation
+\see http://tog.acm.org/resources/GraphicsGems/gemsiv/ptpoly_haines/ptinpoly.c
+\note Does NOT work correctly for point ON border
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
+}
+ */
+
+template
+<
+ typename Point,
+ typename PointOfSegment = Point,
+ typename CalculationType = void
+>
+class crossings_multiply
+{
+ typedef typename select_calculation_type
+ <
+ Point,
+ PointOfSegment,
+ CalculationType
+ >::type calculation_type;
+
+ class flags
+ {
+ bool inside_flag;
+ bool first;
+ bool yflag0;
+
+ public :
+
+ friend class crossings_multiply;
+
+ inline flags()
+ : inside_flag(false)
+ , first(true)
+ , yflag0(false)
+ {}
+ };
+
+public :
+
+ typedef Point point_type;
+ typedef PointOfSegment segment_point_type;
+ typedef flags state_type;
+
+ static inline bool apply(Point const& point,
+ PointOfSegment const& seg1, PointOfSegment const& seg2,
+ flags& state)
+ {
+ calculation_type const tx = get<0>(point);
+ calculation_type const ty = get<1>(point);
+ calculation_type const x0 = get<0>(seg1);
+ calculation_type const y0 = get<1>(seg1);
+ calculation_type const x1 = get<0>(seg2);
+ calculation_type const y1 = get<1>(seg2);
+
+ if (state.first)
+ {
+ state.first = false;
+ state.yflag0 = y0 >= ty;
+ }
+
+
+ bool yflag1 = y1 >= ty;
+ if (state.yflag0 != yflag1)
+ {
+ if ( ((y1-ty) * (x0-x1) >= (x1-tx) * (y0-y1)) == yflag1 )
+ {
+ state.inside_flag = ! state.inside_flag;
+ }
+ }
+ state.yflag0 = yflag1;
+ return true;
+ }
+
+ static inline int result(flags const& state)
+ {
+ return state.inside_flag ? 1 : -1;
+ }
+};
+
+
+
+}} // namespace strategy::within
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
diff --git a/src/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp b/src/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp
new file mode 100644
index 0000000..a774d3c
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp
@@ -0,0 +1,118 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/select_calculation_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace within
+{
+
+/*!
+\brief Within detection using cross counting
+\ingroup strategies
+\tparam Point \tparam_point
+\tparam PointOfSegment \tparam_segment_point
+\tparam CalculationType \tparam_calculation
+\author adapted from Randolph Franklin algorithm
+\author Barend and Maarten, 1995
+\author Revised for templatized library, Barend Gehrels, 2007
+\return true if point is in ring, works for closed rings in both directions
+\note Does NOT work correctly for point ON border
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
+}
+ */
+
+template
+<
+ typename Point,
+ typename PointOfSegment = Point,
+ typename CalculationType = void
+>
+class franklin
+{
+ typedef typename select_calculation_type
+ <
+ Point,
+ PointOfSegment,
+ CalculationType
+ >::type calculation_type;
+
+ /*! subclass to keep state */
+ class crossings
+ {
+ bool crosses;
+
+ public :
+
+ friend class franklin;
+ inline crossings()
+ : crosses(false)
+ {}
+ };
+
+public :
+
+ typedef Point point_type;
+ typedef PointOfSegment segment_point_type;
+ typedef crossings state_type;
+
+ static inline bool apply(Point const& point,
+ PointOfSegment const& seg1, PointOfSegment const& seg2,
+ crossings& state)
+ {
+ calculation_type const& px = get<0>(point);
+ calculation_type const& py = get<1>(point);
+ calculation_type const& x1 = get<0>(seg1);
+ calculation_type const& y1 = get<1>(seg1);
+ calculation_type const& x2 = get<0>(seg2);
+ calculation_type const& y2 = get<1>(seg2);
+
+ if (
+ ( (y2 <= py && py < y1) || (y1 <= py && py < y2) )
+ && (px < (x1 - x2) * (py - y2) / (y1 - y2) + x2)
+ )
+ {
+ state.crosses = ! state.crosses;
+ }
+ return true;
+ }
+
+ static inline int result(crossings const& state)
+ {
+ return state.crosses ? 1 : -1;
+ }
+};
+
+
+
+}} // namespace strategy::within
+
+
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
diff --git a/src/boost/geometry/strategies/cartesian/side_by_triangle.hpp b/src/boost/geometry/strategies/cartesian/side_by_triangle.hpp
new file mode 100644
index 0000000..967090c
--- /dev/null
+++ b/src/boost/geometry/strategies/cartesian/side_by_triangle.hpp
@@ -0,0 +1,121 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/arithmetic/determinant.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+#include <boost/geometry/strategies/side.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace side
+{
+
+/*!
+\brief Check at which side of a segment a point lies:
+ left of segment (> 0), right of segment (< 0), on segment (0)
+\ingroup strategies
+\tparam CalculationType \tparam_calculation
+ */
+template <typename CalculationType = void>
+class side_by_triangle
+{
+public :
+
+ // Template member function, because it is not always trivial
+ // or convenient to explicitly mention the typenames in the
+ // strategy-struct itself.
+
+ // Types can be all three different. Therefore it is
+ // not implemented (anymore) as "segment"
+
+ template <typename P1, typename P2, typename P>
+ static inline int apply(P1 const& p1, P2 const& p2, P const& p)
+ {
+ typedef typename boost::mpl::if_c
+ <
+ boost::is_void<CalculationType>::type::value,
+ typename select_most_precise
+ <
+ typename select_most_precise
+ <
+ typename coordinate_type<P1>::type,
+ typename coordinate_type<P2>::type
+ >::type,
+ typename coordinate_type<P>::type
+ >::type,
+ CalculationType
+ >::type coordinate_type;
+
+ coordinate_type const x = get<0>(p);
+ coordinate_type const y = get<1>(p);
+
+ coordinate_type const sx1 = get<0>(p1);
+ coordinate_type const sy1 = get<1>(p1);
+ coordinate_type const sx2 = get<0>(p2);
+ coordinate_type const sy2 = get<1>(p2);
+
+ // Promote float->double, small int->int
+ typedef typename select_most_precise
+ <
+ coordinate_type,
+ double
+ >::type promoted_type;
+
+ promoted_type const dx = sx2 - sx1;
+ promoted_type const dy = sy2 - sy1;
+ promoted_type const dpx = x - sx1;
+ promoted_type const dpy = y - sy1;
+
+ promoted_type const s
+ = geometry::detail::determinant<promoted_type>
+ (
+ dx, dy,
+ dpx, dpy
+ );
+
+ promoted_type const zero = promoted_type();
+ return math::equals(s, zero) ? 0
+ : s > zero ? 1
+ : -1;
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename CalculationType>
+struct default_strategy<cartesian_tag, CalculationType>
+{
+ typedef side_by_triangle<CalculationType> type;
+};
+
+}
+#endif
+
+}} // namespace strategy::side
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
diff --git a/src/boost/geometry/strategies/centroid.hpp b/src/boost/geometry/strategies/centroid.hpp
new file mode 100644
index 0000000..4963e6b
--- /dev/null
+++ b/src/boost/geometry/strategies/centroid.hpp
@@ -0,0 +1,72 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CENTROID_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CENTROID_HPP
+
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace centroid
+{
+
+struct not_applicable_strategy
+{
+};
+
+
+namespace services
+{
+
+/*!
+ \brief Traits class binding a centroid calculation strategy to a coordinate system
+ \ingroup centroid
+ \tparam CsTag tag of coordinate system, for specialization
+ \tparam GeometryTag tag of geometry, for specialization
+ \tparam Dimension dimension of geometry, for specialization
+ \tparam Point point-type
+ \tparam Geometry
+*/
+template
+<
+ typename CsTag,
+ typename GeometryTag,
+ std::size_t Dimension,
+ typename Point,
+ typename Geometry
+>
+struct default_strategy
+{
+ typedef not_applicable_strategy type;
+};
+
+
+} // namespace services
+
+
+}} // namespace strategy::centroid
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CENTROID_HPP
diff --git a/src/boost/geometry/strategies/compare.hpp b/src/boost/geometry/strategies/compare.hpp
new file mode 100644
index 0000000..2958319
--- /dev/null
+++ b/src/boost/geometry/strategies/compare.hpp
@@ -0,0 +1,172 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_COMPARE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_COMPARE_HPP
+
+#include <cstddef>
+#include <functional>
+
+#include <boost/mpl/if.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+
+#include <boost/geometry/strategies/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+ \brief Traits class binding a comparing strategy to a coordinate system
+ \ingroup util
+ \tparam Tag tag of coordinate system of point-type
+ \tparam Direction direction to compare on: 1 for less (-> ascending order)
+ and -1 for greater (-> descending order)
+ \tparam Point point-type
+ \tparam CoordinateSystem coordinate sytem of point
+ \tparam Dimension: the dimension to compare on
+*/
+template
+<
+ typename Tag,
+ int Direction,
+ typename Point,
+ typename CoordinateSystem,
+ std::size_t Dimension
+>
+struct strategy_compare
+{
+ typedef strategy::not_implemented type;
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+// For compare we add defaults specializations,
+// because they defaultly redirect to std::less / greater / equal_to
+template
+<
+ typename Tag,
+ typename Point,
+ typename CoordinateSystem,
+ std::size_t Dimension
+>
+struct strategy_compare<Tag, 1, Point, CoordinateSystem, Dimension>
+{
+ typedef std::less<typename coordinate_type<Point>::type> type;
+};
+
+
+template
+<
+ typename Tag,
+ typename Point,
+ typename CoordinateSystem,
+ std::size_t Dimension
+>
+struct strategy_compare<Tag, -1, Point, CoordinateSystem, Dimension>
+{
+ typedef std::greater<typename coordinate_type<Point>::type> type;
+};
+
+
+template
+<
+ typename Tag,
+ typename Point,
+ typename CoordinateSystem,
+ std::size_t Dimension
+>
+struct strategy_compare<Tag, 0, Point, CoordinateSystem, Dimension>
+{
+ typedef std::equal_to<typename coordinate_type<Point>::type> type;
+};
+
+
+#endif
+
+
+namespace strategy { namespace compare
+{
+
+
+/*!
+ \brief Default strategy, indicates the default strategy for comparisons
+ \details The default strategy for comparisons defer in most cases
+ to std::less (for ascending) and std::greater (for descending).
+ However, if a spherical coordinate system is used, and comparison
+ is done on longitude, it will take another strategy handling circular
+*/
+struct default_strategy {};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Type>
+struct is_default : boost::false_type
+{};
+
+
+template <>
+struct is_default<default_strategy> : boost::true_type
+{};
+
+
+/*!
+ \brief Meta-function to select strategy
+ \details If "default_strategy" is specified, it will take the
+ traits-registered class for the specified coordinate system.
+ If another strategy is explicitly specified, it takes that one.
+*/
+template
+<
+ typename Strategy,
+ int Direction,
+ typename Point,
+ std::size_t Dimension
+>
+struct select_strategy
+{
+ typedef typename
+ boost::mpl::if_
+ <
+ is_default<Strategy>,
+ typename strategy_compare
+ <
+ typename cs_tag<Point>::type,
+ Direction,
+ Point,
+ typename coordinate_system<Point>::type,
+ Dimension
+ >::type,
+ Strategy
+ >::type type;
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace strategy::compare
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_COMPARE_HPP
diff --git a/src/boost/geometry/strategies/concepts/area_concept.hpp b/src/boost/geometry/strategies/concepts/area_concept.hpp
new file mode 100644
index 0000000..75821b5
--- /dev/null
+++ b/src/boost/geometry/strategies/concepts/area_concept.hpp
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_AREA_CONCEPT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_AREA_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+ \brief Checks strategy for area
+ \ingroup area
+*/
+template <typename Strategy>
+class AreaStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ // 1) must define state_type,
+ typedef typename Strategy::state_type state_type;
+
+ // 2) must define return_type,
+ typedef typename Strategy::return_type return_type;
+
+ // 3) must define point_type, of polygon (segments)
+ typedef typename Strategy::segment_point_type spoint_type;
+
+ struct check_methods
+ {
+ static void apply()
+ {
+ Strategy const* str = 0;
+ state_type *st = 0;
+
+ // 4) must implement a method apply with the following signature
+ spoint_type const* sp = 0;
+ str->apply(*sp, *sp, *st);
+
+ // 5) must implement a static method result with the following signature
+ return_type r = str->result(*st);
+
+ boost::ignore_unused_variable_warning(r);
+ boost::ignore_unused_variable_warning(str);
+ }
+ };
+
+public :
+ BOOST_CONCEPT_USAGE(AreaStrategy)
+ {
+ check_methods::apply();
+ }
+
+#endif
+};
+
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_AREA_CONCEPT_HPP
diff --git a/src/boost/geometry/strategies/concepts/centroid_concept.hpp b/src/boost/geometry/strategies/concepts/centroid_concept.hpp
new file mode 100644
index 0000000..f493ef6
--- /dev/null
+++ b/src/boost/geometry/strategies/concepts/centroid_concept.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_CENTROID_CONCEPT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_CENTROID_CONCEPT_HPP
+
+
+
+#include <boost/concept_check.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+ \brief Checks strategy for centroid
+ \ingroup centroid
+*/
+template <typename Strategy>
+class CentroidStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ // 1) must define state_type,
+ typedef typename Strategy::state_type state_type;
+
+ // 2) must define point_type,
+ typedef typename Strategy::point_type point_type;
+
+ // 3) must define point_type, of polygon (segments)
+ typedef typename Strategy::segment_point_type spoint_type;
+
+ struct check_methods
+ {
+ static void apply()
+ {
+ Strategy *str = 0;
+ state_type *st = 0;
+
+ // 4) must implement a static method apply,
+ // getting two segment-points
+ spoint_type const* sp = 0;
+ str->apply(*sp, *sp, *st);
+
+ // 5) must implement a static method result
+ // getting the centroid
+ point_type *c = 0;
+ bool r = str->result(*st, *c);
+
+ boost::ignore_unused_variable_warning(str);
+ boost::ignore_unused_variable_warning(r);
+ }
+ };
+
+public :
+ BOOST_CONCEPT_USAGE(CentroidStrategy)
+ {
+ check_methods::apply();
+ }
+#endif
+};
+
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_CENTROID_CONCEPT_HPP
diff --git a/src/boost/geometry/strategies/concepts/convex_hull_concept.hpp b/src/boost/geometry/strategies/concepts/convex_hull_concept.hpp
new file mode 100644
index 0000000..b31f0ca
--- /dev/null
+++ b/src/boost/geometry/strategies/concepts/convex_hull_concept.hpp
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
+
+
+#include <vector>
+
+#include <boost/concept_check.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+ \brief Checks strategy for convex_hull
+ \ingroup convex_hull
+*/
+template <typename Strategy>
+class ConvexHullStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ // 1) must define state_type
+ typedef typename Strategy::state_type state_type;
+
+ // 2) must define point_type
+ typedef typename Strategy::point_type point_type;
+
+ // 3) must define geometry_type
+ typedef typename Strategy::geometry_type geometry_type;
+
+ struct check_methods
+ {
+ static void apply()
+ {
+ Strategy const* str;
+
+ state_type* st;
+ geometry_type* sp;
+ std::vector<point_type> *v;
+
+ // 4) must implement a method apply, iterating over a range
+ str->apply(*sp, *st);
+
+ // 5) must implement a method result, with an output iterator
+ str->result(*st, std::back_inserter(*v), true);
+ }
+ };
+
+public :
+ BOOST_CONCEPT_USAGE(ConvexHullStrategy)
+ {
+ check_methods::apply();
+ }
+#endif
+};
+
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
diff --git a/src/boost/geometry/strategies/concepts/distance_concept.hpp b/src/boost/geometry/strategies/concepts/distance_concept.hpp
new file mode 100644
index 0000000..ba347d0
--- /dev/null
+++ b/src/boost/geometry/strategies/concepts/distance_concept.hpp
@@ -0,0 +1,206 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP
+
+#include <vector>
+#include <iterator>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/util/parameter_type_of.hpp>
+
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+ \brief Checks strategy for point-segment-distance
+ \ingroup distance
+*/
+template <typename Strategy>
+struct PointDistanceStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+private :
+
+ struct checker
+ {
+ template <typename ApplyMethod>
+ static void apply(ApplyMethod const&)
+ {
+ // 1: inspect and define both arguments of apply
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 0
+ >::type ptype1;
+
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 1
+ >::type ptype2;
+
+ // 2) check if apply-arguments fulfill point concept
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<ptype1>)
+ );
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<ptype2>)
+ );
+
+
+ // 3) must define meta-function return_type
+ typedef typename strategy::distance::services::return_type<Strategy>::type rtype;
+
+ // 4) must define meta-function "similar_type"
+ typedef typename strategy::distance::services::similar_type
+ <
+ Strategy, ptype2, ptype1
+ >::type stype;
+
+ // 5) must define meta-function "comparable_type"
+ typedef typename strategy::distance::services::comparable_type
+ <
+ Strategy
+ >::type ctype;
+
+ // 6) must define meta-function "tag"
+ typedef typename strategy::distance::services::tag
+ <
+ Strategy
+ >::type tag;
+
+ // 7) must implement apply with arguments
+ Strategy* str = 0;
+ ptype1 *p1 = 0;
+ ptype2 *p2 = 0;
+ rtype r = str->apply(*p1, *p2);
+
+ // 8) must define (meta)struct "get_similar" with apply
+ stype s = strategy::distance::services::get_similar
+ <
+ Strategy,
+ ptype2, ptype1
+ >::apply(*str);
+
+ // 9) must define (meta)struct "get_comparable" with apply
+ ctype c = strategy::distance::services::get_comparable
+ <
+ Strategy
+ >::apply(*str);
+
+ // 10) must define (meta)struct "result_from_distance" with apply
+ r = strategy::distance::services::result_from_distance
+ <
+ Strategy
+ >::apply(*str, 1.0);
+
+ boost::ignore_unused_variable_warning(str);
+ boost::ignore_unused_variable_warning(s);
+ boost::ignore_unused_variable_warning(c);
+ boost::ignore_unused_variable_warning(r);
+ }
+ };
+
+
+
+public :
+ BOOST_CONCEPT_USAGE(PointDistanceStrategy)
+ {
+ checker::apply(&Strategy::apply);
+ }
+#endif
+};
+
+
+/*!
+ \brief Checks strategy for point-segment-distance
+ \ingroup strategy_concepts
+*/
+template <typename Strategy>
+struct PointSegmentDistanceStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+private :
+
+ struct checker
+ {
+ template <typename ApplyMethod>
+ static void apply(ApplyMethod const&)
+ {
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 0
+ >::type ptype;
+
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 1
+ >::type sptype;
+
+ // 2) check if apply-arguments fulfill point concept
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<ptype>)
+ );
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<sptype>)
+ );
+
+
+ // 3) must define meta-function return_type
+ typedef typename strategy::distance::services::return_type<Strategy>::type rtype;
+
+ // 4) must define underlying point-distance-strategy
+ typedef typename strategy::distance::services::strategy_point_point<Strategy>::type stype;
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::PointDistanceStrategy<stype>)
+ );
+
+
+ Strategy *str = 0;
+ ptype *p = 0;
+ sptype *sp1 = 0;
+ sptype *sp2 = 0;
+
+ rtype r = str->apply(*p, *sp1, *sp2);
+
+ boost::ignore_unused_variable_warning(str);
+ boost::ignore_unused_variable_warning(r);
+ }
+ };
+
+public :
+ BOOST_CONCEPT_USAGE(PointSegmentDistanceStrategy)
+ {
+ checker::apply(&Strategy::apply);
+ }
+#endif
+};
+
+
+}}} // namespace boost::geometry::concept
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP
diff --git a/src/boost/geometry/strategies/concepts/segment_intersect_concept.hpp b/src/boost/geometry/strategies/concepts/segment_intersect_concept.hpp
new file mode 100644
index 0000000..43bcccf
--- /dev/null
+++ b/src/boost/geometry/strategies/concepts/segment_intersect_concept.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_SEGMENT_INTERSECT_CONCEPT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_SEGMENT_INTERSECT_CONCEPT_HPP
+
+
+//NOT FINISHED!
+
+#include <boost/concept_check.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+ \brief Checks strategy for segment intersection
+ \ingroup segment_intersection
+*/
+template <typename Strategy>
+class SegmentIntersectStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ // 1) must define return_type
+ typedef typename Strategy::return_type return_type;
+
+ // 2) must define point_type (of segment points)
+ //typedef typename Strategy::point_type point_type;
+
+ // 3) must define segment_type 1 and 2 (of segment points)
+ typedef typename Strategy::segment_type1 segment_type1;
+ typedef typename Strategy::segment_type2 segment_type2;
+
+
+ struct check_methods
+ {
+ static void apply()
+ {
+ Strategy const* str;
+
+ return_type* rt;
+ //point_type const* p;
+ segment_type1 const* s1;
+ segment_type2 const* s2;
+
+ // 4) must implement a method apply
+ // having two segments
+ *rt = str->apply(*s1, *s2);
+
+ }
+ };
+
+
+public :
+ BOOST_CONCEPT_USAGE(SegmentIntersectStrategy)
+ {
+ check_methods::apply();
+ }
+#endif
+};
+
+
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_SEGMENT_INTERSECT_CONCEPT_HPP
diff --git a/src/boost/geometry/strategies/concepts/simplify_concept.hpp b/src/boost/geometry/strategies/concepts/simplify_concept.hpp
new file mode 100644
index 0000000..92e5156
--- /dev/null
+++ b/src/boost/geometry/strategies/concepts/simplify_concept.hpp
@@ -0,0 +1,109 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_SIMPLIFY_CONCEPT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_SIMPLIFY_CONCEPT_HPP
+
+#include <vector>
+#include <iterator>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+ \brief Checks strategy for simplify
+ \ingroup simplify
+*/
+template <typename Strategy>
+struct SimplifyStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+private :
+
+ // 1) must define distance_strategy_type,
+ // defining point-segment distance strategy (to be checked)
+ typedef typename Strategy::distance_strategy_type ds_type;
+
+
+ struct checker
+ {
+ template <typename ApplyMethod>
+ static void apply(ApplyMethod const&)
+ {
+ namespace ft = boost::function_types;
+ typedef typename ft::parameter_types
+ <
+ ApplyMethod
+ >::type parameter_types;
+
+ typedef typename boost::mpl::if_
+ <
+ ft::is_member_function_pointer<ApplyMethod>,
+ boost::mpl::int_<1>,
+ boost::mpl::int_<0>
+ >::type base_index;
+
+ // 1: inspect and define both arguments of apply
+ typedef typename boost::remove_const
+ <
+ typename boost::remove_reference
+ <
+ typename boost::mpl::at
+ <
+ parameter_types,
+ base_index
+ >::type
+ >::type
+ >::type point_type;
+
+
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::PointSegmentDistanceStrategy<ds_type>)
+ );
+
+ Strategy *str = 0;
+ std::vector<point_type> const* v1 = 0;
+ std::vector<point_type> * v2 = 0;
+
+ // 2) must implement method apply with arguments
+ // - Range
+ // - OutputIterator
+ // - floating point value
+ str->apply(*v1, std::back_inserter(*v2), 1.0);
+
+ boost::ignore_unused_variable_warning(str);
+ }
+ };
+
+public :
+ BOOST_CONCEPT_USAGE(SimplifyStrategy)
+ {
+ checker::apply(&ds_type::apply);
+
+ }
+#endif
+};
+
+
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_SIMPLIFY_CONCEPT_HPP
diff --git a/src/boost/geometry/strategies/concepts/within_concept.hpp b/src/boost/geometry/strategies/concepts/within_concept.hpp
new file mode 100644
index 0000000..a9684b9
--- /dev/null
+++ b/src/boost/geometry/strategies/concepts/within_concept.hpp
@@ -0,0 +1,291 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
+
+
+
+#include <boost/concept_check.hpp>
+#include <boost/function_types/result_type.hpp>
+
+#include <boost/geometry/util/parameter_type_of.hpp>
+
+
+namespace boost { namespace geometry { namespace concept
+{
+
+
+/*!
+\brief Checks strategy for within (point-in-polygon)
+\ingroup within
+*/
+template <typename Strategy>
+class WithinStrategyPolygonal
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ // 1) must define state_type
+ typedef typename Strategy::state_type state_type;
+
+ struct checker
+ {
+ template <typename ApplyMethod, typename ResultMethod>
+ static void apply(ApplyMethod const&, ResultMethod const& )
+ {
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 0
+ >::type point_type;
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 1
+ >::type segment_point_type;
+
+ // CHECK: apply-arguments should both fulfill point concept
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<point_type>)
+ );
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<segment_point_type>)
+ );
+
+ // CHECK: return types (result: int, apply: bool)
+ BOOST_MPL_ASSERT_MSG
+ (
+ (boost::is_same
+ <
+ bool, typename boost::function_types::result_type<ApplyMethod>::type
+ >::type::value),
+ WRONG_RETURN_TYPE_OF_APPLY
+ , (bool)
+ );
+ BOOST_MPL_ASSERT_MSG
+ (
+ (boost::is_same
+ <
+ int, typename boost::function_types::result_type<ResultMethod>::type
+ >::type::value),
+ WRONG_RETURN_TYPE_OF_RESULT
+ , (int)
+ );
+
+
+ // CHECK: calling method apply and result
+ Strategy const* str = 0;
+ state_type* st = 0;
+ point_type const* p = 0;
+ segment_point_type const* sp = 0;
+
+ bool b = str->apply(*p, *sp, *sp, *st);
+ int r = str->result(*st);
+
+ boost::ignore_unused_variable_warning(r);
+ boost::ignore_unused_variable_warning(b);
+ boost::ignore_unused_variable_warning(str);
+ }
+ };
+
+
+public :
+ BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
+ {
+ checker::apply(&Strategy::apply, &Strategy::result);
+ }
+#endif
+};
+
+template <typename Strategy>
+class WithinStrategyPointBox
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ struct checker
+ {
+ template <typename ApplyMethod>
+ static void apply(ApplyMethod const&)
+ {
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 0
+ >::type point_type;
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 1
+ >::type box_type;
+
+ // CHECK: apply-arguments should fulfill point/box concept
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<point_type>)
+ );
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstBox<box_type>)
+ );
+
+ // CHECK: return types (apply: bool)
+ BOOST_MPL_ASSERT_MSG
+ (
+ (boost::is_same
+ <
+ bool,
+ typename boost::function_types::result_type<ApplyMethod>::type
+ >::type::value),
+ WRONG_RETURN_TYPE
+ , (bool)
+ );
+
+
+ // CHECK: calling method apply
+ Strategy const* str = 0;
+ point_type const* p = 0;
+ box_type const* bx = 0;
+
+ bool b = str->apply(*p, *bx);
+
+ boost::ignore_unused_variable_warning(b);
+ boost::ignore_unused_variable_warning(str);
+ }
+ };
+
+
+public :
+ BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
+ {
+ checker::apply(&Strategy::apply);
+ }
+#endif
+};
+
+template <typename Strategy>
+class WithinStrategyBoxBox
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ struct checker
+ {
+ template <typename ApplyMethod>
+ static void apply(ApplyMethod const&)
+ {
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 0
+ >::type box_type1;
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 1
+ >::type box_type2;
+
+ // CHECK: apply-arguments should both fulfill box concept
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstBox<box_type1>)
+ );
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstBox<box_type2>)
+ );
+
+ // CHECK: return types (apply: bool)
+ BOOST_MPL_ASSERT_MSG
+ (
+ (boost::is_same
+ <
+ bool,
+ typename boost::function_types::result_type<ApplyMethod>::type
+ >::type::value),
+ WRONG_RETURN_TYPE
+ , (bool)
+ );
+
+
+ // CHECK: calling method apply
+ Strategy const* str = 0;
+ box_type1 const* b1 = 0;
+ box_type2 const* b2 = 0;
+
+ bool b = str->apply(*b1, *b2);
+
+ boost::ignore_unused_variable_warning(b);
+ boost::ignore_unused_variable_warning(str);
+ }
+ };
+
+
+public :
+ BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
+ {
+ checker::apply(&Strategy::apply);
+ }
+#endif
+};
+
+// So now: boost::geometry::concept::within
+namespace within
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
+struct check_within
+{};
+
+
+template <typename AnyTag, typename Strategy>
+struct check_within<point_tag, AnyTag, areal_tag, Strategy>
+{
+ BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Strategy>) );
+};
+
+
+template <typename Strategy>
+struct check_within<point_tag, box_tag, areal_tag, Strategy>
+{
+ BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Strategy>) );
+};
+
+template <typename Strategy>
+struct check_within<box_tag, box_tag, areal_tag, Strategy>
+{
+ BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Strategy>) );
+};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief Checks, in compile-time, the concept of any within-strategy
+\ingroup concepts
+*/
+template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
+inline void check()
+{
+ dispatch::check_within<FirstTag, SecondTag, CastedTag, Strategy> c;
+ boost::ignore_unused_variable_warning(c);
+}
+
+
+}}}} // namespace boost::geometry::concept::within
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
diff --git a/src/boost/geometry/strategies/convex_hull.hpp b/src/boost/geometry/strategies/convex_hull.hpp
new file mode 100644
index 0000000..f4edc5b
--- /dev/null
+++ b/src/boost/geometry/strategies/convex_hull.hpp
@@ -0,0 +1,47 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_HPP
+
+#include <boost/geometry/strategies/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+
+
+/*!
+ \brief Traits class binding a convex hull calculation strategy to a coordinate system
+ \ingroup convex_hull
+ \tparam Tag tag of coordinate system
+ \tparam Geometry the geometry type (hull operates internally per hull over geometry)
+ \tparam Point point-type of output points
+*/
+template
+<
+ typename Geometry1,
+ typename Point,
+ typename CsTag = typename cs_tag<Point>::type
+>
+struct strategy_convex_hull
+{
+ typedef strategy::not_implemented type;
+};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_HPP
diff --git a/src/boost/geometry/strategies/covered_by.hpp b/src/boost/geometry/strategies/covered_by.hpp
new file mode 100644
index 0000000..a878b26
--- /dev/null
+++ b/src/boost/geometry/strategies/covered_by.hpp
@@ -0,0 +1,72 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
+#define BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
+
+#include <boost/mpl/assert.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace covered_by
+{
+
+
+namespace services
+{
+
+/*!
+\brief Traits class binding a covered_by determination strategy to a coordinate system
+\ingroup covered_by
+\tparam TagContained tag (possibly casted) of point-type
+\tparam TagContained tag (possibly casted) of (possibly) containing type
+\tparam CsTagContained tag of coordinate system of point-type
+\tparam CsTagContaining tag of coordinate system of (possibly) containing type
+\tparam Geometry geometry-type of input (often point, or box)
+\tparam GeometryContaining geometry-type of input (possibly) containing type
+*/
+template
+<
+ typename TagContained,
+ typename TagContaining,
+ typename CastedTagContained,
+ typename CastedTagContaining,
+ typename CsTagContained,
+ typename CsTagContaining,
+ typename GeometryContained,
+ typename GeometryContaining
+>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_TYPES
+ , (types<GeometryContained, GeometryContaining>)
+ );
+};
+
+
+} // namespace services
+
+
+}} // namespace strategy::covered_by
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
+
diff --git a/src/boost/geometry/strategies/default_area_result.hpp b/src/boost/geometry/strategies/default_area_result.hpp
new file mode 100644
index 0000000..8adfa5d
--- /dev/null
+++ b/src/boost/geometry/strategies/default_area_result.hpp
@@ -0,0 +1,51 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_DEFAULT_AREA_RESULT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_DEFAULT_AREA_RESULT_HPP
+
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/strategies/area.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Meta-function defining return type of area function, using the default strategy
+\ingroup area
+\note The strategy defines the return-type (so this situation is different
+ from length, where distance is sqr/sqrt, but length always squared)
+ */
+
+template <typename Geometry>
+struct default_area_result
+{
+ typedef typename point_type<Geometry>::type point_type;
+ typedef typename strategy::area::services::default_strategy
+ <
+ typename cs_tag<point_type>::type,
+ point_type
+ >::type strategy_type;
+
+ typedef typename strategy_type::return_type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_DEFAULT_AREA_RESULT_HPP
diff --git a/src/boost/geometry/strategies/default_distance_result.hpp b/src/boost/geometry/strategies/default_distance_result.hpp
new file mode 100644
index 0000000..ea5f3ff
--- /dev/null
+++ b/src/boost/geometry/strategies/default_distance_result.hpp
@@ -0,0 +1,50 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_DEFAULT_DISTANCE_RESULT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_DEFAULT_DISTANCE_RESULT_HPP
+
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Meta-function defining return type of distance function
+\ingroup distance
+\note The strategy defines the return-type (so this situation is different
+ from length, where distance is sqr/sqrt, but length always squared)
+ */
+template <typename Geometry1, typename Geometry2 = Geometry1>
+struct default_distance_result
+{
+ typedef typename strategy::distance::services::return_type
+ <
+ typename strategy::distance::services::default_strategy
+ <
+ point_tag,
+ typename point_type<Geometry1>::type,
+ typename point_type<Geometry2>::type
+ >::type
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_DEFAULT_DISTANCE_RESULT_HPP
diff --git a/src/boost/geometry/strategies/default_length_result.hpp b/src/boost/geometry/strategies/default_length_result.hpp
new file mode 100644
index 0000000..706941b
--- /dev/null
+++ b/src/boost/geometry/strategies/default_length_result.hpp
@@ -0,0 +1,46 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_DEFAULT_LENGTH_RESULT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_DEFAULT_LENGTH_RESULT_HPP
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+ \brief Meta-function defining return type of length function
+ \ingroup length
+ \note Length of a line of integer coordinates can be double.
+ So we take at least a double. If Big Number types are used,
+ we take that type.
+
+ */
+template <typename Geometry>
+struct default_length_result
+{
+ typedef typename select_most_precise
+ <
+ typename coordinate_type<Geometry>::type,
+ long double
+ >::type type;
+};
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_DEFAULT_LENGTH_RESULT_HPP
diff --git a/src/boost/geometry/strategies/distance.hpp b/src/boost/geometry/strategies/distance.hpp
new file mode 100644
index 0000000..ef9a7ee
--- /dev/null
+++ b/src/boost/geometry/strategies/distance.hpp
@@ -0,0 +1,135 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_DISTANCE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace distance { namespace services
+{
+
+
+template <typename Strategy> struct tag {};
+template <typename Strategy> struct return_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY, (types<Strategy>)
+ );
+};
+
+
+/*!
+ \brief Metafunction delivering a similar strategy with other input point types
+*/
+template
+<
+ typename Strategy,
+ typename Point1,
+ typename Point2
+>
+struct similar_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY
+ , (types<Strategy, Point1, Point2>)
+ );
+};
+
+template
+<
+ typename Strategy,
+ typename Point1,
+ typename Point2
+>
+struct get_similar
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY
+ , (types<Strategy, Point1, Point2>)
+ );
+};
+
+template <typename Strategy> struct comparable_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY, (types<Strategy>)
+ );
+};
+
+template <typename Strategy> struct get_comparable
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_STRATEGY, (types<Strategy>)
+ );
+};
+
+template <typename Strategy> struct result_from_distance {};
+
+
+// For point-segment only:
+template <typename Strategy> struct strategy_point_point {};
+
+
+// Default strategy
+
+
+/*!
+ \brief Traits class binding a default strategy for distance
+ to one (or possibly two) coordinate system(s)
+ \ingroup distance
+ \tparam GeometryTag tag (point/segment) for which this strategy is the default
+ \tparam Point1 first point-type
+ \tparam Point2 second point-type
+ \tparam CsTag1 tag of coordinate system of first point type
+ \tparam CsTag2 tag of coordinate system of second point type
+*/
+template
+<
+ typename GeometryTag,
+ typename Point1,
+ typename Point2 = Point1,
+ typename CsTag1 = typename cs_tag<Point1>::type,
+ typename CsTag2 = typename cs_tag<Point2>::type,
+ typename UnderlyingStrategy = void
+>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE_COMBINATION
+ , (types<Point1, Point2, CsTag1, CsTag2>)
+ );
+};
+
+
+}}} // namespace strategy::distance::services
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_DISTANCE_HPP
diff --git a/src/boost/geometry/strategies/intersection.hpp b/src/boost/geometry/strategies/intersection.hpp
new file mode 100644
index 0000000..fc628c0
--- /dev/null
+++ b/src/boost/geometry/strategies/intersection.hpp
@@ -0,0 +1,93 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_INTERSECTION_HPP
+#define BOOST_GEOMETRY_STRATEGIES_INTERSECTION_HPP
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+#include <boost/geometry/policies/relate/intersection_points.hpp>
+#include <boost/geometry/policies/relate/direction.hpp>
+#include <boost/geometry/policies/relate/tupled.hpp>
+
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
+#include <boost/geometry/strategies/intersection_result.hpp>
+
+#include <boost/geometry/strategies/cartesian/cart_intersect.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+// The intersection strategy is a "compound strategy",
+// it contains a segment-intersection-strategy
+// and a side-strategy
+/*!
+\tparam CalculationType \tparam_calculation
+*/
+template
+<
+ typename Tag,
+ typename Geometry1,
+ typename Geometry2,
+ typename IntersectionPoint,
+ typename CalculationType = void
+>
+struct strategy_intersection
+{
+private :
+ typedef typename geometry::point_type<Geometry1>::type point1_type;
+ typedef typename geometry::point_type<Geometry2>::type point2_type;
+ typedef typename model::referring_segment<point1_type const> segment1_type;
+ typedef typename model::referring_segment<point2_type const> segment2_type;
+
+ typedef segment_intersection_points
+ <
+ IntersectionPoint
+ > ip_type;
+
+public:
+ typedef strategy::intersection::relate_cartesian_segments
+ <
+ policies::relate::segments_tupled
+ <
+ policies::relate::segments_intersection_points
+ <
+ segment1_type,
+ segment2_type,
+ ip_type,
+ CalculationType
+ > ,
+ policies::relate::segments_direction
+ <
+ segment1_type,
+ segment2_type,
+ CalculationType
+ >,
+ CalculationType
+ >,
+ CalculationType
+ > segment_intersection_strategy_type;
+
+ typedef typename strategy::side::services::default_strategy
+ <
+ Tag,
+ CalculationType
+ >::type side_strategy_type;
+};
+
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_INTERSECTION_HPP
diff --git a/src/boost/geometry/strategies/intersection_result.hpp b/src/boost/geometry/strategies/intersection_result.hpp
new file mode 100644
index 0000000..15917a9
--- /dev/null
+++ b/src/boost/geometry/strategies/intersection_result.hpp
@@ -0,0 +1,174 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_INTERSECTION_RESULT_HPP
+#define BOOST_GEOMETRY_STRATEGIES_INTERSECTION_RESULT_HPP
+
+#if defined(HAVE_MATRIX_AS_STRING)
+#include <string>
+#endif
+
+#include <cstddef>
+
+
+namespace boost { namespace geometry
+{
+
+/*!
+ \brief Dimensionally Extended 9 Intersection Matrix
+ \details
+ \ingroup overlay
+ \see http://gis.hsr.ch/wiki/images/3/3d/9dem_springer.pdf
+*/
+struct de9im
+{
+ int ii, ib, ie,
+ bi, bb, be,
+ ei, eb, ee;
+
+ inline de9im()
+ : ii(-1), ib(-1), ie(-1)
+ , bi(-1), bb(-1), be(-1)
+ , ei(-1), eb(-1), ee(-1)
+ {
+ }
+
+ inline de9im(int ii0, int ib0, int ie0,
+ int bi0, int bb0, int be0,
+ int ei0, int eb0, int ee0)
+ : ii(ii0), ib(ib0), ie(ie0)
+ , bi(bi0), bb(bb0), be(be0)
+ , ei(ei0), eb(eb0), ee(ee0)
+ {}
+
+ inline bool equals() const
+ {
+ return ii >= 0 && ie < 0 && be < 0 && ei < 0 && eb < 0;
+ }
+
+ inline bool disjoint() const
+ {
+ return ii < 0 && ib < 0 && bi < 0 && bb < 0;
+ }
+
+ inline bool intersects() const
+ {
+ return ii >= 0 || bb >= 0 || bi >= 0 || ib >= 0;
+ }
+
+ inline bool touches() const
+ {
+ return ii < 0 && (bb >= 0 || bi >= 0 || ib >= 0);
+ }
+
+ inline bool crosses() const
+ {
+ return (ii >= 0 && ie >= 0) || (ii == 0);
+ }
+
+ inline bool overlaps() const
+ {
+ return ii >= 0 && ie >= 0 && ei >= 0;
+ }
+
+ inline bool within() const
+ {
+ return ii >= 0 && ie < 0 && be < 0;
+ }
+
+ inline bool contains() const
+ {
+ return ii >= 0 && ei < 0 && eb < 0;
+ }
+
+
+ static inline char as_char(int v)
+ {
+ return v >= 0 && v < 10 ? ('0' + char(v)) : '-';
+ }
+
+#if defined(HAVE_MATRIX_AS_STRING)
+ inline std::string matrix_as_string(std::string const& tab, std::string const& nl) const
+ {
+ std::string ret;
+ ret.reserve(9 + tab.length() * 3 + nl.length() * 3);
+ ret += tab; ret += as_char(ii); ret += as_char(ib); ret += as_char(ie); ret += nl;
+ ret += tab; ret += as_char(bi); ret += as_char(bb); ret += as_char(be); ret += nl;
+ ret += tab; ret += as_char(ei); ret += as_char(eb); ret += as_char(ee);
+ return ret;
+ }
+
+ inline std::string matrix_as_string() const
+ {
+ return matrix_as_string("", "");
+ }
+#endif
+
+};
+
+struct de9im_segment : public de9im
+{
+ bool collinear; // true if segments are aligned (for equal,overlap,touch)
+ bool opposite; // true if direction is reversed (for equal,overlap,touch)
+ bool parallel; // true if disjoint but parallel
+ bool degenerate; // true for segment(s) of zero length
+
+ double ra, rb; // temp
+
+ inline de9im_segment()
+ : de9im()
+ , collinear(false)
+ , opposite(false)
+ , parallel(false)
+ , degenerate(false)
+ {}
+
+ inline de9im_segment(double a, double b,
+ int ii0, int ib0, int ie0,
+ int bi0, int bb0, int be0,
+ int ei0, int eb0, int ee0,
+ bool c = false, bool o = false, bool p = false, bool d = false)
+ : de9im(ii0, ib0, ie0, bi0, bb0, be0, ei0, eb0, ee0)
+ , collinear(c)
+ , opposite(o)
+ , parallel(p)
+ , degenerate(d)
+ , ra(a), rb(b)
+ {}
+
+
+#if defined(HAVE_MATRIX_AS_STRING)
+ inline std::string as_string() const
+ {
+ std::string ret = matrix_as_string();
+ ret += collinear ? "c" : "-";
+ ret += opposite ? "o" : "-";
+ return ret;
+ }
+#endif
+};
+
+
+
+template <typename Point>
+struct segment_intersection_points
+{
+ std::size_t count;
+ Point intersections[2];
+ typedef Point point_type;
+
+ segment_intersection_points()
+ : count(0)
+ {}
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_INTERSECTION_RESULT_HPP
diff --git a/src/boost/geometry/strategies/side.hpp b/src/boost/geometry/strategies/side.hpp
new file mode 100644
index 0000000..376f2fd
--- /dev/null
+++ b/src/boost/geometry/strategies/side.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SIDE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SIDE_HPP
+
+
+#include <boost/geometry/strategies/tags.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace side
+{
+
+namespace services
+{
+
+/*!
+\brief Traits class binding a side determination strategy to a coordinate system
+\ingroup util
+\tparam Tag tag of coordinate system of point-type
+\tparam CalculationType \tparam_calculation
+*/
+template <typename Tag, typename CalculationType = void>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_TYPE
+ , (types<Tag>)
+ );
+};
+
+
+} // namespace services
+
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SIDE_HPP
diff --git a/src/boost/geometry/strategies/side_info.hpp b/src/boost/geometry/strategies/side_info.hpp
new file mode 100644
index 0000000..f3a9da0
--- /dev/null
+++ b/src/boost/geometry/strategies/side_info.hpp
@@ -0,0 +1,166 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP
+
+
+#include <utility>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief Class side_info: small class wrapping for sides (-1,0,1)
+*/
+class side_info
+{
+public :
+ inline side_info(int side_a1 = 0, int side_a2 = 0,
+ int side_b1 = 0, int side_b2 = 0)
+ {
+ sides[0].first = side_a1;
+ sides[0].second = side_a2;
+ sides[1].first = side_b1;
+ sides[1].second = side_b2;
+ }
+
+ template <int Which>
+ inline void set(int first, int second)
+ {
+ sides[Which].first = first;
+ sides[Which].second = second;
+ }
+
+ template <int Which, int Index>
+ inline void correct_to_zero()
+ {
+ if (Index == 0)
+ {
+ sides[Which].first = 0;
+ }
+ else
+ {
+ sides[Which].second = 0;
+ }
+ }
+
+ template <int Which, int Index>
+ inline int get() const
+ {
+ return Index == 0 ? sides[Which].first : sides[Which].second;
+ }
+
+
+ // Returns true if both lying on the same side WRT the other
+ // (so either 1,1 or -1-1)
+ template <int Which>
+ inline bool same() const
+ {
+ return sides[Which].first * sides[Which].second == 1;
+ }
+
+ inline bool collinear() const
+ {
+ return sides[0].first == 0
+ && sides[0].second == 0
+ && sides[1].first == 0
+ && sides[1].second == 0;
+ }
+
+ inline bool crossing() const
+ {
+ return sides[0].first * sides[0].second == -1
+ && sides[1].first * sides[1].second == -1;
+ }
+
+ inline bool touching() const
+ {
+ return (sides[0].first * sides[1].first == -1
+ && sides[0].second == 0 && sides[1].second == 0)
+ || (sides[1].first * sides[0].first == -1
+ && sides[1].second == 0 && sides[0].second == 0);
+ }
+
+ template <int Which>
+ inline bool one_touching() const
+ {
+ // This is normally a situation which can't occur:
+ // If one is completely left or right, the other cannot touch
+ return one_zero<Which>()
+ && sides[1 - Which].first * sides[1 - Which].second == 1;
+ }
+
+ inline bool meeting() const
+ {
+ // Two of them (in each segment) zero, two not
+ return one_zero<0>() && one_zero<1>();
+ }
+
+ template <int Which>
+ inline bool zero() const
+ {
+ return sides[Which].first == 0 && sides[Which].second == 0;
+ }
+
+ template <int Which>
+ inline bool one_zero() const
+ {
+ return (sides[Which].first == 0 && sides[Which].second != 0)
+ || (sides[Which].first != 0 && sides[Which].second == 0);
+ }
+
+ inline bool one_of_all_zero() const
+ {
+ int const sum = std::abs(sides[0].first)
+ + std::abs(sides[0].second)
+ + std::abs(sides[1].first)
+ + std::abs(sides[1].second);
+ return sum == 3;
+ }
+
+
+ template <int Which>
+ inline int zero_index() const
+ {
+ return sides[Which].first == 0 ? 0 : 1;
+ }
+
+
+ inline void debug() const
+ {
+ std::cout << sides[0].first << " "
+ << sides[0].second << " "
+ << sides[1].first << " "
+ << sides[1].second
+ << std::endl;
+ }
+
+
+ inline void reverse()
+ {
+ std::swap(sides[0], sides[1]);
+ }
+
+//private :
+ std::pair<int, int> sides[2];
+
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP
diff --git a/src/boost/geometry/strategies/spherical/area_huiller.hpp b/src/boost/geometry/strategies/spherical/area_huiller.hpp
new file mode 100644
index 0000000..1bef9b5
--- /dev/null
+++ b/src/boost/geometry/strategies/spherical/area_huiller.hpp
@@ -0,0 +1,202 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_HUILLER_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_HUILLER_HPP
+
+
+
+#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
+
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace area
+{
+
+
+
+/*!
+\brief Area calculation by spherical excess / Huiller's formula
+\ingroup strategies
+\tparam PointOfSegment point type of segments of rings/polygons
+\tparam CalculationType \tparam_calculation
+\author Barend Gehrels. Adapted from:
+- http://www.soe.ucsc.edu/~pang/160/f98/Gems/GemsIV/sph_poly.c
+- http://williams.best.vwh.net/avform.htm
+\note The version in Gems didn't account for polygons crossing the 180 meridian.
+\note This version works for convex and non-convex polygons, for 180 meridian
+crossing polygons and for polygons with holes. However, some cases (especially
+180 meridian cases) must still be checked.
+\note The version which sums angles, which is often seen, doesn't handle non-convex
+polygons correctly.
+\note The version which sums longitudes, see
+http://trs-new.jpl.nasa.gov/dspace/bitstream/2014/40409/1/07-03.pdf, is simple
+and works well in most cases but not in 180 meridian crossing cases. This probably
+could be solved.
+
+\note This version is made for spherical equatorial coordinate systems
+
+\qbk{
+
+[heading Example]
+[area_with_strategy]
+[area_with_strategy_output]
+
+
+[heading See also]
+[link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
+}
+
+*/
+template
+<
+ typename PointOfSegment,
+ typename CalculationType = void
+>
+class huiller
+{
+typedef typename boost::mpl::if_c
+ <
+ boost::is_void<CalculationType>::type::value,
+ typename select_most_precise
+ <
+ typename coordinate_type<PointOfSegment>::type,
+ double
+ >::type,
+ CalculationType
+ >::type calculation_type;
+
+protected :
+ struct excess_sum
+ {
+ calculation_type sum;
+
+ // Distances are calculated on unit sphere here
+ strategy::distance::haversine<PointOfSegment, PointOfSegment>
+ distance_over_unit_sphere;
+
+
+ inline excess_sum()
+ : sum(0)
+ , distance_over_unit_sphere(1)
+ {}
+ inline calculation_type area(calculation_type radius) const
+ {
+ return - sum * radius * radius;
+ }
+ };
+
+public :
+ typedef calculation_type return_type;
+ typedef PointOfSegment segment_point_type;
+ typedef excess_sum state_type;
+
+ inline huiller(calculation_type radius = 1.0)
+ : m_radius(radius)
+ {}
+
+ inline void apply(PointOfSegment const& p1,
+ PointOfSegment const& p2,
+ excess_sum& state) const
+ {
+ if (! geometry::math::equals(get<0>(p1), get<0>(p2)))
+ {
+ calculation_type const half = 0.5;
+ calculation_type const two = 2.0;
+ calculation_type const four = 4.0;
+ calculation_type const two_pi = two * geometry::math::pi<calculation_type>();
+ calculation_type const half_pi = half * geometry::math::pi<calculation_type>();
+
+ // Distance p1 p2
+ calculation_type a = state.distance_over_unit_sphere.apply(p1, p2);
+
+ // Sides on unit sphere to south pole
+ calculation_type b = half_pi - geometry::get_as_radian<1>(p2);
+ calculation_type c = half_pi - geometry::get_as_radian<1>(p1);
+
+ // Semi parameter
+ calculation_type s = half * (a + b + c);
+
+ // E: spherical excess, using l'Huiller's formula
+ // [tg(e / 4)]2 = tg[s / 2] tg[(s-a) / 2] tg[(s-b) / 2] tg[(s-c) / 2]
+ calculation_type E = four * atan(sqrt(geometry::math::abs(tan(s / two)
+ * tan((s - a) / two)
+ * tan((s - b) / two)
+ * tan((s - c) / two))));
+
+ E = geometry::math::abs(E);
+
+ // In right direction: positive, add area. In left direction: negative, subtract area.
+ // Longitude comparisons are not so obvious. If one is negative, other is positive,
+ // we have to take the dateline into account.
+ // TODO: check this / enhance this, should be more robust. See also the "grow" for ll
+ // TODO: use minmax or "smaller"/"compare" strategy for this
+ calculation_type lon1 = geometry::get_as_radian<0>(p1) < 0
+ ? geometry::get_as_radian<0>(p1) + two_pi
+ : geometry::get_as_radian<0>(p1);
+
+ calculation_type lon2 = geometry::get_as_radian<0>(p2) < 0
+ ? geometry::get_as_radian<0>(p2) + two_pi
+ : geometry::get_as_radian<0>(p2);
+
+ if (lon2 < lon1)
+ {
+ E = -E;
+ }
+
+ state.sum += E;
+ }
+ }
+
+ inline return_type result(excess_sum const& state) const
+ {
+ return state.area(m_radius);
+ }
+
+private :
+ /// Radius of the sphere
+ calculation_type m_radius;
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+
+template <typename Point>
+struct default_strategy<spherical_equatorial_tag, Point>
+{
+ typedef strategy::area::huiller<Point> type;
+};
+
+// Note: spherical polar coordinate system requires "get_as_radian_equatorial"
+/***template <typename Point>
+struct default_strategy<spherical_polar_tag, Point>
+{
+ typedef strategy::area::huiller<Point> type;
+};***/
+
+} // namespace services
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::area
+
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_AREA_HUILLER_HPP
diff --git a/src/boost/geometry/strategies/spherical/compare_circular.hpp b/src/boost/geometry/strategies/spherical/compare_circular.hpp
new file mode 100644
index 0000000..2f890df
--- /dev/null
+++ b/src/boost/geometry/strategies/spherical/compare_circular.hpp
@@ -0,0 +1,152 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace compare
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Units>
+struct shift
+{
+};
+
+template <>
+struct shift<degree>
+{
+ static inline double full() { return 360.0; }
+ static inline double half() { return 180.0; }
+};
+
+template <>
+struct shift<radian>
+{
+ static inline double full() { return 2.0 * boost::math::constants::pi<double>(); }
+ static inline double half() { return boost::math::constants::pi<double>(); }
+};
+
+} // namespace detail
+#endif
+
+/*!
+\brief Compare (in one direction) strategy for spherical coordinates
+\ingroup strategies
+\tparam Point point-type
+\tparam Dimension dimension
+*/
+template <typename CoordinateType, typename Units, typename Compare>
+struct circular_comparator
+{
+ static inline CoordinateType put_in_range(CoordinateType const& c,
+ double min_border, double max_border)
+ {
+ CoordinateType value = c;
+ while (value < min_border)
+ {
+ value += detail::shift<Units>::full();
+ }
+ while (value > max_border)
+ {
+ value -= detail::shift<Units>::full();
+ }
+ return value;
+ }
+
+ inline bool operator()(CoordinateType const& c1, CoordinateType const& c2) const
+ {
+ Compare compare;
+
+ // Check situation that one of them is e.g. std::numeric_limits.
+ static const double full = detail::shift<Units>::full();
+ double mx = 10.0 * full;
+ if (c1 < -mx || c1 > mx || c2 < -mx || c2 > mx)
+ {
+ // do normal comparison, using circular is not useful
+ return compare(c1, c2);
+ }
+
+ static const double half = full / 2.0;
+ CoordinateType v1 = put_in_range(c1, -half, half);
+ CoordinateType v2 = put_in_range(c2, -half, half);
+
+ // Two coordinates on a circle are
+ // at max <= half a circle away from each other.
+ // So if it is more, shift origin.
+ CoordinateType diff = geometry::math::abs(v1 - v2);
+ if (diff > half)
+ {
+ v1 = put_in_range(v1, 0, full);
+ v2 = put_in_range(v2, 0, full);
+ }
+
+ return compare(v1, v2);
+ }
+};
+
+}} // namespace strategy::compare
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+// Specialize for the longitude (dim 0)
+template
+<
+ typename Point,
+ template<typename> class CoordinateSystem,
+ typename Units
+>
+struct strategy_compare<spherical_polar_tag, 1, Point, CoordinateSystem<Units>, 0>
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+ typedef strategy::compare::circular_comparator
+ <
+ coordinate_type,
+ Units,
+ std::less<coordinate_type>
+ > type;
+};
+
+template
+<
+ typename Point,
+ template<typename> class CoordinateSystem,
+ typename Units
+>
+struct strategy_compare<spherical_polar_tag, -1, Point, CoordinateSystem<Units>, 0>
+{
+ typedef typename coordinate_type<Point>::type coordinate_type;
+ typedef strategy::compare::circular_comparator
+ <
+ coordinate_type,
+ Units,
+ std::greater<coordinate_type>
+ > type;
+};
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
diff --git a/src/boost/geometry/strategies/spherical/distance_cross_track.hpp b/src/boost/geometry/strategies/spherical/distance_cross_track.hpp
new file mode 100644
index 0000000..ba58922
--- /dev/null
+++ b/src/boost/geometry/strategies/spherical/distance_cross_track.hpp
@@ -0,0 +1,349 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+
+#include <boost/geometry/util/promote_floating_point.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
+# include <boost/geometry/io/dsv/write.hpp>
+#endif
+
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace distance
+{
+
+/*!
+\brief Strategy functor for distance point to segment calculation
+\ingroup strategies
+\details Class which calculates the distance of a point to a segment, using latlong points
+\see http://williams.best.vwh.net/avform.htm
+\tparam Point point type
+\tparam PointOfSegment \tparam_segment_point
+\tparam CalculationType \tparam_calculation
+\tparam Strategy underlying point-point distance strategy, defaults to haversine
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
+}
+
+*/
+template
+<
+ typename Point,
+ typename PointOfSegment = Point,
+ typename CalculationType = void,
+ typename Strategy = typename services::default_strategy<point_tag, Point>::type
+>
+class cross_track
+{
+public :
+ typedef typename promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point,
+ PointOfSegment,
+ CalculationType
+ >::type
+ >::type return_type;
+
+ inline cross_track()
+ {
+ m_strategy = Strategy();
+ m_radius = m_strategy.radius();
+ }
+
+ inline cross_track(return_type const& r)
+ : m_radius(r)
+ , m_strategy(r)
+ {}
+
+ inline cross_track(Strategy const& s)
+ : m_strategy(s)
+ {
+ m_radius = m_strategy.radius();
+ }
+
+
+ // It might be useful in the future
+ // to overload constructor with strategy info.
+ // crosstrack(...) {}
+
+
+ inline return_type apply(Point const& p,
+ PointOfSegment const& sp1, PointOfSegment const& sp2) const
+ {
+ // http://williams.best.vwh.net/avform.htm#XTE
+ return_type d1 = m_strategy.apply(sp1, p);
+
+ // Actually, calculation of d2 not necessary if we know that the projected point is on the great circle...
+ return_type d2 = m_strategy.apply(sp2, p);
+
+ return_type crs_AD = course(sp1, p);
+ return_type crs_AB = course(sp1, sp2);
+ return_type XTD = m_radius * geometry::math::abs(asin(sin(d1 / m_radius) * sin(crs_AD - crs_AB)));
+
+#ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK
+std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " " << crs_AD * geometry::math::r2d << std::endl;
+std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " " << crs_AB * geometry::math::r2d << std::endl;
+std::cout << "XTD: " << XTD << " d1: " << d1 << " d2: " << d2 << std::endl;
+#endif
+
+
+ // Return shortest distance, either to projected point on segment sp1-sp2, or to sp1, or to sp2
+ return return_type((std::min)((std::min)(d1, d2), XTD));
+ }
+
+ inline return_type radius() const { return m_radius; }
+
+private :
+ BOOST_CONCEPT_ASSERT
+ (
+ (geometry::concept::PointDistanceStrategy<Strategy >)
+ );
+
+
+ return_type m_radius;
+
+ // Point-point distances are calculated in radians, on the unit sphere
+ Strategy m_strategy;
+
+ /// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
+ inline return_type course(Point const& p1, Point const& p2) const
+ {
+ // http://williams.best.vwh.net/avform.htm#Crs
+ return_type dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
+ return_type cos_p2lat = cos(get_as_radian<1>(p2));
+
+ // "An alternative formula, not requiring the pre-computation of d"
+ return atan2(sin(dlon) * cos_p2lat,
+ cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
+ - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
+ }
+
+};
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct tag<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef strategy_tag_distance_point_segment type;
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct return_type<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef typename cross_track<Point, PointOfSegment, CalculationType, Strategy>::return_type type;
+};
+
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy,
+ typename P,
+ typename PS
+>
+struct similar_type<cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS>
+{
+ typedef cross_track<Point, PointOfSegment, CalculationType, Strategy> type;
+};
+
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy,
+ typename P,
+ typename PS
+>
+struct get_similar<cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS>
+{
+ static inline typename similar_type
+ <
+ cross_track<Point, PointOfSegment, CalculationType, Strategy>, P, PS
+ >::type apply(cross_track<Point, PointOfSegment, CalculationType, Strategy> const& strategy)
+ {
+ return cross_track<P, PS, CalculationType, Strategy>(strategy.radius());
+ }
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct comparable_type<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ // Comparable type is here just the strategy
+ typedef typename similar_type
+ <
+ cross_track
+ <
+ Point, PointOfSegment, CalculationType, Strategy
+ >, Point, PointOfSegment
+ >::type type;
+};
+
+
+template
+<
+ typename Point, typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy
+>
+struct get_comparable<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef typename comparable_type
+ <
+ cross_track<Point, PointOfSegment, CalculationType, Strategy>
+ >::type comparable_type;
+public :
+ static inline comparable_type apply(cross_track<Point, PointOfSegment, CalculationType, Strategy> const& strategy)
+ {
+ return comparable_type(strategy.radius());
+ }
+};
+
+
+template
+<
+ typename Point, typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy
+>
+struct result_from_distance<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
+{
+private :
+ typedef typename cross_track<Point, PointOfSegment, CalculationType, Strategy>::return_type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(cross_track<Point, PointOfSegment, CalculationType, Strategy> const& , T const& distance)
+ {
+ return distance;
+ }
+};
+
+
+template
+<
+ typename Point, typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy
+>
+struct strategy_point_point<cross_track<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef Strategy type;
+};
+
+
+
+/*
+
+TODO: spherical polar coordinate system requires "get_as_radian_equatorial<>"
+
+template <typename Point, typename PointOfSegment, typename Strategy>
+struct default_strategy
+ <
+ segment_tag, Point, PointOfSegment,
+ spherical_polar_tag, spherical_polar_tag,
+ Strategy
+ >
+{
+ typedef cross_track
+ <
+ Point,
+ PointOfSegment,
+ void,
+ typename boost::mpl::if_
+ <
+ boost::is_void<Strategy>,
+ typename default_strategy
+ <
+ point_tag, Point, PointOfSegment,
+ spherical_polar_tag, spherical_polar_tag
+ >::type,
+ Strategy
+ >::type
+ > type;
+};
+*/
+
+template <typename Point, typename PointOfSegment, typename Strategy>
+struct default_strategy
+ <
+ segment_tag, Point, PointOfSegment,
+ spherical_equatorial_tag, spherical_equatorial_tag,
+ Strategy
+ >
+{
+ typedef cross_track
+ <
+ Point,
+ PointOfSegment,
+ void,
+ typename boost::mpl::if_
+ <
+ boost::is_void<Strategy>,
+ typename default_strategy
+ <
+ point_tag, Point, PointOfSegment,
+ spherical_equatorial_tag, spherical_equatorial_tag
+ >::type,
+ Strategy
+ >::type
+ > type;
+};
+
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+#endif
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
diff --git a/src/boost/geometry/strategies/spherical/distance_haversine.hpp b/src/boost/geometry/strategies/spherical/distance_haversine.hpp
new file mode 100644
index 0000000..59ec1c3
--- /dev/null
+++ b/src/boost/geometry/strategies/spherical/distance_haversine.hpp
@@ -0,0 +1,330 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
+
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace distance
+{
+
+
+namespace comparable
+{
+
+// Comparable haversine.
+// To compare distances, we can avoid:
+// - multiplication with radius and 2.0
+// - applying sqrt
+// - applying asin (which is strictly (monotone) increasing)
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
+class haversine
+{
+public :
+ typedef typename promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type
+ >::type calculation_type;
+
+ inline haversine(calculation_type const& r = 1.0)
+ : m_radius(r)
+ {}
+
+
+ static inline calculation_type apply(Point1 const& p1, Point2 const& p2)
+ {
+ return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
+ get_as_radian<0>(p2), get_as_radian<1>(p2));
+ }
+
+ inline calculation_type radius() const
+ {
+ return m_radius;
+ }
+
+
+private :
+
+ static inline calculation_type calculate(calculation_type const& lon1,
+ calculation_type const& lat1,
+ calculation_type const& lon2,
+ calculation_type const& lat2)
+ {
+ return math::hav(lat2 - lat1)
+ + cos(lat1) * cos(lat2) * math::hav(lon2 - lon1);
+ }
+
+ calculation_type m_radius;
+};
+
+
+
+} // namespace comparable
+
+/*!
+\brief Distance calculation for spherical coordinates
+on a perfect sphere using haversine
+\ingroup strategies
+\tparam Point1 \tparam_first_point
+\tparam Point2 \tparam_second_point
+\tparam CalculationType \tparam_calculation
+\author Adapted from: http://williams.best.vwh.net/avform.htm
+\see http://en.wikipedia.org/wiki/Great-circle_distance
+\note It says: <em>The great circle distance d between two
+points with coordinates {lat1,lon1} and {lat2,lon2} is given by:
+ d=acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2))
+A mathematically equivalent formula, which is less subject
+ to rounding error for short distances is:
+ d=2*asin(sqrt((sin((lat1-lat2)/2))^2
+ + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
+ </em>
+
+\qbk{
+[heading See also]
+[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
+}
+
+*/
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
+class haversine
+{
+ typedef comparable::haversine<Point1, Point2, CalculationType> comparable_type;
+
+public :
+
+ typedef typename services::return_type<comparable_type>::type calculation_type;
+
+ /*!
+ \brief Constructor
+ \param radius radius of the sphere, defaults to 1.0 for the unit sphere
+ */
+ inline haversine(calculation_type const& radius = 1.0)
+ : m_radius(radius)
+ {}
+
+ /*!
+ \brief applies the distance calculation
+ \return the calculated distance (including multiplying with radius)
+ \param p1 first point
+ \param p2 second point
+ */
+ inline calculation_type apply(Point1 const& p1, Point2 const& p2) const
+ {
+ calculation_type const a = comparable_type::apply(p1, p2);
+ calculation_type const c = calculation_type(2.0) * asin(sqrt(a));
+ return m_radius * c;
+ }
+
+ /*!
+ \brief access to radius value
+ \return the radius
+ */
+ inline calculation_type radius() const
+ {
+ return m_radius;
+ }
+
+private :
+ calculation_type m_radius;
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct tag<haversine<Point1, Point2, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct return_type<haversine<Point1, Point2, CalculationType> >
+{
+ typedef typename haversine<Point1, Point2, CalculationType>::calculation_type type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
+struct similar_type<haversine<Point1, Point2, CalculationType>, P1, P2>
+{
+ typedef haversine<P1, P2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
+struct get_similar<haversine<Point1, Point2, CalculationType>, P1, P2>
+{
+private :
+ typedef haversine<Point1, Point2, CalculationType> this_type;
+public :
+ static inline typename similar_type<this_type, P1, P2>::type apply(this_type const& input)
+ {
+ return haversine<P1, P2, CalculationType>(input.radius());
+ }
+};
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct comparable_type<haversine<Point1, Point2, CalculationType> >
+{
+ typedef comparable::haversine<Point1, Point2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct get_comparable<haversine<Point1, Point2, CalculationType> >
+{
+private :
+ typedef haversine<Point1, Point2, CalculationType> this_type;
+ typedef comparable::haversine<Point1, Point2, CalculationType> comparable_type;
+public :
+ static inline comparable_type apply(this_type const& input)
+ {
+ return comparable_type(input.radius());
+ }
+};
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct result_from_distance<haversine<Point1, Point2, CalculationType> >
+{
+private :
+ typedef haversine<Point1, Point2, CalculationType> this_type;
+ typedef typename return_type<this_type>::type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(this_type const& , T const& value)
+ {
+ return return_type(value);
+ }
+};
+
+
+// Specializations for comparable::haversine
+template <typename Point1, typename Point2, typename CalculationType>
+struct tag<comparable::haversine<Point1, Point2, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct return_type<comparable::haversine<Point1, Point2, CalculationType> >
+{
+ typedef typename comparable::haversine<Point1, Point2, CalculationType>::calculation_type type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
+struct similar_type<comparable::haversine<Point1, Point2, CalculationType>, P1, P2>
+{
+ typedef comparable::haversine<P1, P2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
+struct get_similar<comparable::haversine<Point1, Point2, CalculationType>, P1, P2>
+{
+private :
+ typedef comparable::haversine<Point1, Point2, CalculationType> this_type;
+public :
+ static inline typename similar_type<this_type, P1, P2>::type apply(this_type const& input)
+ {
+ return comparable::haversine<P1, P2, CalculationType>(input.radius());
+ }
+};
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct comparable_type<comparable::haversine<Point1, Point2, CalculationType> >
+{
+ typedef comparable::haversine<Point1, Point2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct get_comparable<comparable::haversine<Point1, Point2, CalculationType> >
+{
+private :
+ typedef comparable::haversine<Point1, Point2, CalculationType> this_type;
+public :
+ static inline this_type apply(this_type const& input)
+ {
+ return input;
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct result_from_distance<comparable::haversine<Point1, Point2, CalculationType> >
+{
+private :
+ typedef comparable::haversine<Point1, Point2, CalculationType> strategy_type;
+ typedef typename return_type<strategy_type>::type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(strategy_type const& strategy, T const& distance)
+ {
+ return_type const s = sin((distance / strategy.radius()) / return_type(2));
+ return s * s;
+ }
+};
+
+
+// Register it as the default for point-types
+// in a spherical equatorial coordinate system
+template <typename Point1, typename Point2>
+struct default_strategy<point_tag, Point1, Point2, spherical_equatorial_tag, spherical_equatorial_tag>
+{
+ typedef strategy::distance::haversine<Point1, Point2> type;
+};
+
+// Note: spherical polar coordinate system requires "get_as_radian_equatorial"
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
diff --git a/src/boost/geometry/strategies/spherical/side_by_cross_track.hpp b/src/boost/geometry/strategies/spherical/side_by_cross_track.hpp
new file mode 100644
index 0000000..b7cf279
--- /dev/null
+++ b/src/boost/geometry/strategies/spherical/side_by_cross_track.hpp
@@ -0,0 +1,100 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SIDE_BY_CROSS_TRACK_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SIDE_BY_CROSS_TRACK_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/strategies/side.hpp>
+//#include <boost/geometry/strategies/concepts/side_concept.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace side
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+/// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
+template <typename Point>
+static inline double course(Point const& p1, Point const& p2)
+{
+ // http://williams.best.vwh.net/avform.htm#Crs
+ double dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
+ double cos_p2lat = cos(get_as_radian<1>(p2));
+
+ // "An alternative formula, not requiring the pre-computation of d"
+ return atan2(sin(dlon) * cos_p2lat,
+ cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
+ - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
+}
+
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+/*!
+\brief Check at which side of a Great Circle segment a point lies
+ left of segment (> 0), right of segment (< 0), on segment (0)
+\ingroup strategies
+\tparam CalculationType \tparam_calculation
+ */
+template <typename CalculationType = void>
+class side_by_cross_track
+{
+
+public :
+ template <typename P1, typename P2, typename P>
+ static inline int apply(P1 const& p1, P2 const& p2, P const& p)
+ {
+ typedef typename boost::mpl::if_c
+ <
+ boost::is_void<CalculationType>::type::value,
+ typename select_most_precise
+ <
+ typename select_most_precise
+ <
+ typename coordinate_type<P1>::type,
+ typename coordinate_type<P2>::type
+ >::type,
+ typename coordinate_type<P>::type
+ >::type,
+ CalculationType
+ >::type coordinate_type;
+
+ double d1 = 0.001; // m_strategy.apply(sp1, p);
+ double crs_AD = detail::course(p1, p);
+ double crs_AB = detail::course(p1, p2);
+ double XTD = asin(sin(d1) * sin(crs_AD - crs_AB));
+
+ return math::equals(XTD, 0) ? 0 : XTD < 0 ? 1 : -1;
+ }
+};
+
+}} // namespace strategy::side
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SIDE_BY_CROSS_TRACK_HPP
diff --git a/src/boost/geometry/strategies/spherical/ssf.hpp b/src/boost/geometry/strategies/spherical/ssf.hpp
new file mode 100644
index 0000000..ab7c675
--- /dev/null
+++ b/src/boost/geometry/strategies/spherical/ssf.hpp
@@ -0,0 +1,136 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP
+#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+#include <boost/geometry/util/math.hpp>
+
+#include <boost/geometry/strategies/side.hpp>
+//#include <boost/geometry/strategies/concepts/side_concept.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace side
+{
+
+
+/*!
+\brief Check at which side of a Great Circle segment a point lies
+ left of segment (> 0), right of segment (< 0), on segment (0)
+\ingroup strategies
+\tparam CalculationType \tparam_calculation
+ */
+template <typename CalculationType = void>
+class spherical_side_formula
+{
+
+public :
+ template <typename P1, typename P2, typename P>
+ static inline int apply(P1 const& p1, P2 const& p2, P const& p)
+ {
+ typedef typename boost::mpl::if_c
+ <
+ boost::is_void<CalculationType>::type::value,
+
+ // Select at least a double...
+ typename select_most_precise
+ <
+ typename select_most_precise
+ <
+ typename select_most_precise
+ <
+ typename coordinate_type<P1>::type,
+ typename coordinate_type<P2>::type
+ >::type,
+ typename coordinate_type<P>::type
+ >::type,
+ double
+ >::type,
+ CalculationType
+ >::type coordinate_type;
+
+ // Convenient shortcuts
+ typedef coordinate_type ct;
+ ct const lambda1 = get_as_radian<0>(p1);
+ ct const delta1 = get_as_radian<1>(p1);
+ ct const lambda2 = get_as_radian<0>(p2);
+ ct const delta2 = get_as_radian<1>(p2);
+ ct const lambda = get_as_radian<0>(p);
+ ct const delta = get_as_radian<1>(p);
+
+ // Create temporary points (vectors) on unit a sphere
+ ct const cos_delta1 = cos(delta1);
+ ct const c1x = cos_delta1 * cos(lambda1);
+ ct const c1y = cos_delta1 * sin(lambda1);
+ ct const c1z = sin(delta1);
+
+ ct const cos_delta2 = cos(delta2);
+ ct const c2x = cos_delta2 * cos(lambda2);
+ ct const c2y = cos_delta2 * sin(lambda2);
+ ct const c2z = sin(delta2);
+
+ // (Third point is converted directly)
+ ct const cos_delta = cos(delta);
+
+ // Apply the "Spherical Side Formula" as presented on my blog
+ ct const dist
+ = (c1y * c2z - c1z * c2y) * cos_delta * cos(lambda)
+ + (c1z * c2x - c1x * c2z) * cos_delta * sin(lambda)
+ + (c1x * c2y - c1y * c2x) * sin(delta);
+
+ ct zero = ct();
+ return dist > zero ? 1
+ : dist < zero ? -1
+ : 0;
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+/*template <typename CalculationType>
+struct default_strategy<spherical_polar_tag, CalculationType>
+{
+ typedef spherical_side_formula<CalculationType> type;
+};*/
+
+template <typename CalculationType>
+struct default_strategy<spherical_equatorial_tag, CalculationType>
+{
+ typedef spherical_side_formula<CalculationType> type;
+};
+
+template <typename CalculationType>
+struct default_strategy<geographic_tag, CalculationType>
+{
+ typedef spherical_side_formula<CalculationType> type;
+};
+
+}
+#endif
+
+}} // namespace strategy::side
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SSF_HPP
diff --git a/src/boost/geometry/strategies/strategies.hpp b/src/boost/geometry/strategies/strategies.hpp
new file mode 100644
index 0000000..3aa9ab0
--- /dev/null
+++ b/src/boost/geometry/strategies/strategies.hpp
@@ -0,0 +1,59 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_STRATEGIES_HPP
+#define BOOST_GEOMETRY_STRATEGIES_STRATEGIES_HPP
+
+
+#include <boost/geometry/strategies/tags.hpp>
+
+#include <boost/geometry/strategies/area.hpp>
+#include <boost/geometry/strategies/centroid.hpp>
+#include <boost/geometry/strategies/compare.hpp>
+#include <boost/geometry/strategies/convex_hull.hpp>
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/transform.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+#include <boost/geometry/strategies/cartesian/area_surveyor.hpp>
+#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
+#include <boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp>
+#include <boost/geometry/strategies/cartesian/centroid_weighted_length.hpp>
+#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
+#include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+
+#include <boost/geometry/strategies/spherical/area_huiller.hpp>
+#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
+#include <boost/geometry/strategies/spherical/compare_circular.hpp>
+#include <boost/geometry/strategies/spherical/ssf.hpp>
+
+#include <boost/geometry/strategies/agnostic/hull_graham_andrew.hpp>
+#include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
+#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
+#include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+
+#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
+#include <boost/geometry/strategies/transform/map_transformer.hpp>
+#include <boost/geometry/strategies/transform/inverse_transformer.hpp>
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_STRATEGIES_HPP
diff --git a/src/boost/geometry/strategies/strategy_transform.hpp b/src/boost/geometry/strategies/strategy_transform.hpp
new file mode 100644
index 0000000..61a408c
--- /dev/null
+++ b/src/boost/geometry/strategies/strategy_transform.hpp
@@ -0,0 +1,504 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_STRATEGY_TRANSFORM_HPP
+#define BOOST_GEOMETRY_STRATEGIES_STRATEGY_TRANSFORM_HPP
+
+#include <cstddef>
+#include <cmath>
+#include <functional>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <boost/geometry/algorithms/convert.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/radian_access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/transform.hpp>
+
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace transform
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template
+<
+ typename Src, typename Dst,
+ std::size_t D, std::size_t N,
+ template <typename> class F
+>
+struct transform_coordinates
+{
+ template <typename T>
+ static inline void transform(Src const& source, Dst& dest, T value)
+ {
+ typedef typename select_coordinate_type<Src, Dst>::type coordinate_type;
+
+ F<coordinate_type> function;
+ set<D>(dest, boost::numeric_cast<coordinate_type>(function(get<D>(source), value)));
+ transform_coordinates<Src, Dst, D + 1, N, F>::transform(source, dest, value);
+ }
+};
+
+template
+<
+ typename Src, typename Dst,
+ std::size_t N,
+ template <typename> class F
+>
+struct transform_coordinates<Src, Dst, N, N, F>
+{
+ template <typename T>
+ static inline void transform(Src const& , Dst& , T )
+ {
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+ \brief Transformation strategy to copy one point to another using assignment operator
+ \ingroup transform
+ \tparam P point type
+ */
+template <typename P>
+struct copy_direct
+{
+ inline bool apply(P const& p1, P& p2) const
+ {
+ p2 = p1;
+ return true;
+ }
+};
+
+/*!
+ \brief Transformation strategy to do copy a point, copying per coordinate.
+ \ingroup transform
+ \tparam P1 first point type
+ \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct copy_per_coordinate
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ // Defensive check, dimensions are equal, selected by specialization
+ assert_dimension_equal<P1, P2>();
+
+ geometry::convert(p1, p2);
+ return true;
+ }
+};
+
+
+/*!
+ \brief Transformation strategy to go from degree to radian and back
+ \ingroup transform
+ \tparam P1 first point type
+ \tparam P2 second point type
+ \tparam F additional functor to divide or multiply with d2r
+ */
+template <typename P1, typename P2, template <typename> class F>
+struct degree_radian_vv
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ // Spherical coordinates always have 2 coordinates measured in angles
+ // The optional third one is distance/height, provided in another strategy
+ // Polar coordinates having one angle, will be also in another strategy
+ assert_dimension<P1, 2>();
+ assert_dimension<P2, 2>();
+
+ detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+ return true;
+ }
+};
+
+template <typename P1, typename P2, template <typename> class F>
+struct degree_radian_vv_3
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 3>();
+ assert_dimension<P2, 3>();
+
+ detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+ // Copy height or other third dimension
+ set<2>(p2, get<2>(p1));
+ return true;
+ }
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+ /// Helper function for conversion, phi/theta are in radians
+ template <typename P, typename T, typename R>
+ inline void spherical_polar_to_cartesian(T phi, T theta, R r, P& p)
+ {
+ assert_dimension<P, 3>();
+
+ // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_spherical_coordinates
+ // http://www.vias.org/comp_geometry/math_coord_convert_3d.htm
+ // https://moodle.polymtl.ca/file.php/1183/Autres_Documents/Derivation_for_Spherical_Co-ordinates.pdf
+ // http://en.citizendium.org/wiki/Spherical_polar_coordinates
+
+ // Phi = first, theta is second, r is third, see documentation on cs::spherical
+
+ // (calculations are splitted to implement ttmath)
+
+ T r_sin_theta = r;
+ T r_cos_theta = r;
+ r_sin_theta *= sin(theta);
+ r_cos_theta *= cos(theta);
+
+ set<0>(p, r_sin_theta * cos(phi));
+ set<1>(p, r_sin_theta * sin(phi));
+ set<2>(p, r_cos_theta);
+ }
+
+ /// Helper function for conversion, lambda/delta (lon lat) are in radians
+ template <typename P, typename T, typename R>
+ inline void spherical_equatorial_to_cartesian(T lambda, T delta, R r, P& p)
+ {
+ assert_dimension<P, 3>();
+
+ // http://mathworld.wolfram.com/GreatCircle.html
+ // http://www.spenvis.oma.be/help/background/coortran/coortran.html WRONG
+
+ T r_cos_delta = r;
+ T r_sin_delta = r;
+ r_cos_delta *= cos(delta);
+ r_sin_delta *= sin(delta);
+
+ set<0>(p, r_cos_delta * cos(lambda));
+ set<1>(p, r_cos_delta * sin(lambda));
+ set<2>(p, r_sin_delta);
+ }
+
+
+ /// Helper function for conversion
+ template <typename P, typename T>
+ inline bool cartesian_to_spherical2(T x, T y, T z, P& p)
+ {
+ assert_dimension<P, 2>();
+
+ // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
+
+#if defined(BOOST_GEOMETRY_TRANSFORM_CHECK_UNIT_SPHERE)
+ // TODO: MAYBE ONLY IF TO BE CHECKED?
+ T const r = /*sqrt not necessary, sqrt(1)=1*/ (x * x + y * y + z * z);
+
+ // Unit sphere, so r should be 1
+ if (geometry::math::abs(r - 1.0) > T(1e-6))
+ {
+ return false;
+ }
+ // end todo
+#endif
+
+ set_from_radian<0>(p, atan2(y, x));
+ set_from_radian<1>(p, acos(z));
+ return true;
+ }
+
+ template <typename P, typename T>
+ inline bool cartesian_to_spherical_equatorial2(T x, T y, T z, P& p)
+ {
+ assert_dimension<P, 2>();
+
+ set_from_radian<0>(p, atan2(y, x));
+ set_from_radian<1>(p, asin(z));
+ return true;
+ }
+
+
+ template <typename P, typename T>
+ inline bool cartesian_to_spherical3(T x, T y, T z, P& p)
+ {
+ assert_dimension<P, 3>();
+
+ // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
+ T const r = sqrt(x * x + y * y + z * z);
+ set<2>(p, r);
+ set_from_radian<0>(p, atan2(y, x));
+ if (r > 0.0)
+ {
+ set_from_radian<1>(p, acos(z / r));
+ return true;
+ }
+ return false;
+ }
+
+ template <typename P, typename T>
+ inline bool cartesian_to_spherical_equatorial3(T x, T y, T z, P& p)
+ {
+ assert_dimension<P, 3>();
+
+ // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
+ T const r = sqrt(x * x + y * y + z * z);
+ set<2>(p, r);
+ set_from_radian<0>(p, atan2(y, x));
+ if (r > 0.0)
+ {
+ set_from_radian<1>(p, asin(z / r));
+ return true;
+ }
+ return false;
+ }
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+ \brief Transformation strategy for 2D spherical (phi,theta) to 3D cartesian (x,y,z)
+ \details on Unit sphere
+ \ingroup transform
+ \tparam P1 first point type
+ \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_spherical_polar_2_to_cartesian_3
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 2>();
+ detail::spherical_polar_to_cartesian(get_as_radian<0>(p1), get_as_radian<1>(p1), 1.0, p2);
+ return true;
+ }
+};
+
+template <typename P1, typename P2>
+struct from_spherical_equatorial_2_to_cartesian_3
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 2>();
+ detail::spherical_equatorial_to_cartesian(get_as_radian<0>(p1), get_as_radian<1>(p1), 1.0, p2);
+ return true;
+ }
+};
+
+
+/*!
+ \brief Transformation strategy for 3D spherical (phi,theta,r) to 3D cartesian (x,y,z)
+ \ingroup transform
+ \tparam P1 first point type
+ \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_spherical_polar_3_to_cartesian_3
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 3>();
+ detail::spherical_polar_to_cartesian(
+ get_as_radian<0>(p1), get_as_radian<1>(p1), get<2>(p1), p2);
+ return true;
+ }
+};
+
+template <typename P1, typename P2>
+struct from_spherical_equatorial_3_to_cartesian_3
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 3>();
+ detail::spherical_equatorial_to_cartesian(
+ get_as_radian<0>(p1), get_as_radian<1>(p1), get<2>(p1), p2);
+ return true;
+ }
+};
+
+
+/*!
+ \brief Transformation strategy for 3D cartesian (x,y,z) to 2D spherical (phi,theta)
+ \details on Unit sphere
+ \ingroup transform
+ \tparam P1 first point type
+ \tparam P2 second point type
+ \note If x,y,z point is not lying on unit sphere, transformation will return false
+ */
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_polar_2
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 3>();
+ return detail::cartesian_to_spherical2(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+ }
+};
+
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_equatorial_2
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 3>();
+ return detail::cartesian_to_spherical_equatorial2(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+ }
+};
+
+
+/*!
+ \brief Transformation strategy for 3D cartesian (x,y,z) to 3D spherical (phi,theta,r)
+ \ingroup transform
+ \tparam P1 first point type
+ \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_polar_3
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 3>();
+ return detail::cartesian_to_spherical3(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+ }
+};
+
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_equatorial_3
+{
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension<P1, 3>();
+ return detail::cartesian_to_spherical_equatorial3(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+ }
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+namespace services
+{
+
+/// Specialization for same coordinate system family, same system, same dimension, same point type, can be copied
+template <typename CoordSysTag, typename CoordSys, std::size_t D, typename P>
+struct default_strategy<CoordSysTag, CoordSysTag, CoordSys, CoordSys, D, D, P, P>
+{
+ typedef copy_direct<P> type;
+};
+
+/// Specialization for same coordinate system family and system, same dimension, different point type, copy per coordinate
+template <typename CoordSysTag, typename CoordSys, std::size_t D, typename P1, typename P2>
+struct default_strategy<CoordSysTag, CoordSysTag, CoordSys, CoordSys, D, D, P1, P2>
+{
+ typedef copy_per_coordinate<P1, P2> type;
+};
+
+/// Specialization to transform from degree to radian for any coordinate system / point type combination
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct default_strategy<CoordSysTag, CoordSysTag, CoordSys<degree>, CoordSys<radian>, 2, 2, P1, P2>
+{
+ typedef degree_radian_vv<P1, P2, std::multiplies> type;
+};
+
+/// Specialization to transform from radian to degree for any coordinate system / point type combination
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct default_strategy<CoordSysTag, CoordSysTag, CoordSys<radian>, CoordSys<degree>, 2, 2, P1, P2>
+{
+ typedef degree_radian_vv<P1, P2, std::divides> type;
+};
+
+
+/// Specialization degree->radian in 3D
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct default_strategy<CoordSysTag, CoordSysTag, CoordSys<degree>, CoordSys<radian>, 3, 3, P1, P2>
+{
+ typedef degree_radian_vv_3<P1, P2, std::multiplies> type;
+};
+
+/// Specialization radian->degree in 3D
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct default_strategy<CoordSysTag, CoordSysTag, CoordSys<radian>, CoordSys<degree>, 3, 3, P1, P2>
+{
+ typedef degree_radian_vv_3<P1, P2, std::divides> type;
+};
+
+/// Specialization to transform from unit sphere(phi,theta) to XYZ
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<spherical_polar_tag, cartesian_tag, CoordSys1, CoordSys2, 2, 3, P1, P2>
+{
+ typedef from_spherical_polar_2_to_cartesian_3<P1, P2> type;
+};
+
+/// Specialization to transform from sphere(phi,theta,r) to XYZ
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<spherical_polar_tag, cartesian_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+ typedef from_spherical_polar_3_to_cartesian_3<P1, P2> type;
+};
+
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<spherical_equatorial_tag, cartesian_tag, CoordSys1, CoordSys2, 2, 3, P1, P2>
+{
+ typedef from_spherical_equatorial_2_to_cartesian_3<P1, P2> type;
+};
+
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<spherical_equatorial_tag, cartesian_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+ typedef from_spherical_equatorial_3_to_cartesian_3<P1, P2> type;
+};
+
+/// Specialization to transform from XYZ to unit sphere(phi,theta)
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<cartesian_tag, spherical_polar_tag, CoordSys1, CoordSys2, 3, 2, P1, P2>
+{
+ typedef from_cartesian_3_to_spherical_polar_2<P1, P2> type;
+};
+
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<cartesian_tag, spherical_equatorial_tag, CoordSys1, CoordSys2, 3, 2, P1, P2>
+{
+ typedef from_cartesian_3_to_spherical_equatorial_2<P1, P2> type;
+};
+
+/// Specialization to transform from XYZ to sphere(phi,theta,r)
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<cartesian_tag, spherical_polar_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+ typedef from_cartesian_3_to_spherical_polar_3<P1, P2> type;
+};
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct default_strategy<cartesian_tag, spherical_equatorial_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+ typedef from_cartesian_3_to_spherical_equatorial_3<P1, P2> type;
+};
+
+
+} // namespace services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::transform
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_STRATEGY_TRANSFORM_HPP
diff --git a/src/boost/geometry/strategies/tags.hpp b/src/boost/geometry/strategies/tags.hpp
new file mode 100644
index 0000000..39f2f23
--- /dev/null
+++ b/src/boost/geometry/strategies/tags.hpp
@@ -0,0 +1,41 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_TAGS_HPP
+#define BOOST_GEOMETRY_STRATEGIES_TAGS_HPP
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy
+{
+ /*!
+ \brief Indicate compiler/library user that strategy is not implemented.
+ \details Strategies are defined for point types or for point type
+ combinations. If there is no implementation for that specific point type, or point type
+ combination, the calculation cannot be done. To indicate this, this not_implemented
+ class is used as a typedef stub.
+
+ */
+ struct not_implemented {};
+}
+
+
+struct strategy_tag_distance_point_point {};
+struct strategy_tag_distance_point_segment {};
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_TAGS_HPP
diff --git a/src/boost/geometry/strategies/transform.hpp b/src/boost/geometry/strategies/transform.hpp
new file mode 100644
index 0000000..3c806ac
--- /dev/null
+++ b/src/boost/geometry/strategies/transform.hpp
@@ -0,0 +1,63 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_TRANSFORM_HPP
+#define BOOST_GEOMETRY_STRATEGIES_TRANSFORM_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/assert.hpp>
+
+#include <boost/geometry/strategies/tags.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace transform { namespace services
+{
+
+/*!
+ \brief Traits class binding a transformation strategy to a coordinate system
+ \ingroup transform
+ \details Can be specialized
+ - per coordinate system family (tag)
+ - per coordinate system (or groups of them)
+ - per dimension
+ - per point type
+ \tparam CoordinateSystemTag 1,2 coordinate system tags
+ \tparam CoordinateSystem 1,2 coordinate system
+ \tparam D 1, 2 dimension
+ \tparam Point 1, 2 point type
+ */
+template
+<
+ typename CoordinateSystemTag1, typename CoordinateSystemTag2,
+ typename CoordinateSystem1, typename CoordinateSystem2,
+ std::size_t Dimension1, std::size_t Dimension2,
+ typename Point1, typename Point2
+>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPES
+ , (types<Point1, Point2>)
+ );
+};
+
+}}} // namespace strategy::transform::services
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_TRANSFORM_HPP
diff --git a/src/boost/geometry/strategies/transform/inverse_transformer.hpp b/src/boost/geometry/strategies/transform/inverse_transformer.hpp
new file mode 100644
index 0000000..845a71d
--- /dev/null
+++ b/src/boost/geometry/strategies/transform/inverse_transformer.hpp
@@ -0,0 +1,78 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
+#define BOOST_GEOMETRY_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
+
+// Remove the ublas checking, otherwise the inverse might fail
+// (while nothing seems to be wrong)
+#define BOOST_UBLAS_TYPE_CHECK 0
+
+#include <boost/numeric/ublas/lu.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace transform
+{
+
+/*!
+\brief Transformation strategy to do an inverse ransformation in Cartesian system
+\ingroup strategies
+\tparam P1 first point type
+\tparam P2 second point type
+ */
+template <typename P1, typename P2>
+class inverse_transformer
+ : public ublas_transformer<P1, P2, dimension<P1>::type::value, dimension<P2>::type::value>
+{
+ typedef typename select_coordinate_type<P1, P2>::type T;
+
+public :
+ template <typename Transformer>
+ inline inverse_transformer(Transformer const& input)
+ {
+ typedef boost::numeric::ublas::matrix<T> matrix_type;
+
+ // create a working copy of the input
+ matrix_type copy(input.matrix());
+
+ // create a permutation matrix for the LU-factorization
+ typedef boost::numeric::ublas::permutation_matrix<> permutation_matrix;
+ permutation_matrix pm(copy.size1());
+
+ // perform LU-factorization
+ int res = boost::numeric::ublas::lu_factorize<matrix_type>(copy, pm);
+ if( res == 0 )
+ {
+ // create identity matrix
+ this->m_matrix.assign(boost::numeric::ublas::identity_matrix<T>(copy.size1()));
+
+ // backsubstitute to get the inverse
+ boost::numeric::ublas::lu_substitute(copy, pm, this->m_matrix);
+ }
+ }
+
+};
+
+
+}} // namespace strategy::transform
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
diff --git a/src/boost/geometry/strategies/transform/map_transformer.hpp b/src/boost/geometry/strategies/transform/map_transformer.hpp
new file mode 100644
index 0000000..150ff1d
--- /dev/null
+++ b/src/boost/geometry/strategies/transform/map_transformer.hpp
@@ -0,0 +1,165 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
+#define BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
+
+
+#include <cstddef>
+
+#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace transform
+{
+
+/*!
+\brief Transformation strategy to do map from one to another Cartesian system
+\ingroup strategies
+\tparam P1 first point type
+\tparam P2 second point type
+\tparam Mirror if true map is mirrored upside-down (in most cases pixels
+ are from top to bottom, while map is from bottom to top)
+ */
+template
+<
+ typename P1, typename P2,
+ bool Mirror = false, bool SameScale = true,
+ std::size_t Dimension1 = dimension<P1>::type::value,
+ std::size_t Dimension2 = dimension<P2>::type::value
+>
+class map_transformer
+ : public ublas_transformer<P1, P2, Dimension1, Dimension2>
+{
+ typedef typename select_coordinate_type<P1, P2>::type T;
+ typedef boost::numeric::ublas::matrix<T> M;
+
+public :
+ template <typename B, typename D>
+ explicit inline map_transformer(B const& box, D const& width, D const& height)
+ {
+ set_transformation(
+ get<min_corner, 0>(box), get<min_corner, 1>(box),
+ get<max_corner, 0>(box), get<max_corner, 1>(box),
+ width, height);
+ }
+
+ template <typename W, typename D>
+ explicit inline map_transformer(W const& wx1, W const& wy1, W const& wx2, W const& wy2,
+ D const& width, D const& height)
+ {
+ set_transformation(wx1, wy1, wx2, wy2, width, height);
+ }
+
+
+private :
+ template <typename W, typename P, typename S>
+ inline void set_transformation_point(W const& wx, W const& wy,
+ P const& px, P const& py,
+ S const& scalex, S const& scaley)
+ {
+
+ // Translate to a coordinate system centered on world coordinates (-wx, -wy)
+ M t1(3,3);
+ t1(0,0) = 1; t1(0,1) = 0; t1(0,2) = -wx;
+ t1(1,0) = 0; t1(1,1) = 1; t1(1,2) = -wy;
+ t1(2,0) = 0; t1(2,1) = 0; t1(2,2) = 1;
+
+ // Scale the map
+ M s(3,3);
+ s(0,0) = scalex; s(0,1) = 0; s(0,2) = 0;
+ s(1,0) = 0; s(1,1) = scaley; s(1,2) = 0;
+ s(2,0) = 0; s(2,1) = 0; s(2,2) = 1;
+
+ // Translate to a coordinate system centered on the specified pixels (+px, +py)
+ M t2(3, 3);
+ t2(0,0) = 1; t2(0,1) = 0; t2(0,2) = px;
+ t2(1,0) = 0; t2(1,1) = 1; t2(1,2) = py;
+ t2(2,0) = 0; t2(2,1) = 0; t2(2,2) = 1;
+
+ // Calculate combination matrix in two steps
+ this->m_matrix = boost::numeric::ublas::prod(s, t1);
+ this->m_matrix = boost::numeric::ublas::prod(t2, this->m_matrix);
+ }
+
+
+ template <typename W, typename D>
+ void set_transformation(W const& wx1, W const& wy1, W const& wx2, W const& wy2,
+ D const& width, D const& height)
+ {
+ D px1 = 0;
+ D py1 = 0;
+ D px2 = width;
+ D py2 = height;
+
+ // Get the same type, but at least a double
+ typedef typename select_most_precise<D, double>::type type;
+
+
+ // Calculate appropriate scale, take min because whole box must fit
+ // Scale is in PIXELS/MAPUNITS (meters)
+ W wdx = wx2 - wx1;
+ W wdy = wy2 - wy1;
+ type sx = (px2 - px1) / boost::numeric_cast<type>(wdx);
+ type sy = (py2 - py1) / boost::numeric_cast<type>(wdy);
+
+ if (SameScale)
+ {
+ type scale = (std::min)(sx, sy);
+ sx = scale;
+ sy = scale;
+ }
+
+ // Calculate centerpoints
+ W wtx = wx1 + wx2;
+ W wty = wy1 + wy2;
+ W two = 2;
+ W wmx = wtx / two;
+ W wmy = wty / two;
+ type pmx = (px1 + px2) / 2.0;
+ type pmy = (py1 + py2) / 2.0;
+
+ set_transformation_point(wmx, wmy, pmx, pmy, sx, sy);
+
+ if (Mirror)
+ {
+ // Mirror in y-direction
+ M m(3,3);
+ m(0,0) = 1; m(0,1) = 0; m(0,2) = 0;
+ m(1,0) = 0; m(1,1) = -1; m(1,2) = 0;
+ m(2,0) = 0; m(2,1) = 0; m(2,2) = 1;
+
+ // Translate in y-direction such that it fits again
+ M y(3, 3);
+ y(0,0) = 1; y(0,1) = 0; y(0,2) = 0;
+ y(1,0) = 0; y(1,1) = 1; y(1,2) = height;
+ y(2,0) = 0; y(2,1) = 0; y(2,2) = 1;
+
+ // Calculate combination matrix in two steps
+ this->m_matrix = boost::numeric::ublas::prod(m, this->m_matrix);
+ this->m_matrix = boost::numeric::ublas::prod(y, this->m_matrix);
+ }
+ }
+};
+
+
+}} // namespace strategy::transform
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
diff --git a/src/boost/geometry/strategies/transform/matrix_transformers.hpp b/src/boost/geometry/strategies/transform/matrix_transformers.hpp
new file mode 100644
index 0000000..68da240
--- /dev/null
+++ b/src/boost/geometry/strategies/transform/matrix_transformers.hpp
@@ -0,0 +1,422 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
+#define BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
+
+
+#include <cstddef>
+
+// Remove the ublas checking, otherwise the inverse might fail
+// (while nothing seems to be wrong)
+#define BOOST_UBLAS_TYPE_CHECK 0
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_coordinate_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace transform
+{
+
+/*!
+\brief Affine transformation strategy in Cartesian system.
+\details The strategy serves as a generic definition of affine transformation matrix
+ and procedure of application it to given point.
+\see http://en.wikipedia.org/wiki/Affine_transformation
+ and http://www.devmaster.net/wiki/Transformation_matrices
+\ingroup strategies
+\tparam P1 first point type (source)
+\tparam P2 second point type (target)
+\tparam Dimension1 number of dimensions to transform from first point
+\tparam Dimension1 number of dimensions to transform to second point
+ */
+template
+<
+ typename P1, typename P2,
+ std::size_t Dimension1,
+ std::size_t Dimension2
+>
+class ublas_transformer
+{
+};
+
+
+template <typename P1, typename P2>
+class ublas_transformer<P1, P2, 2, 2>
+{
+protected :
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+ typedef coordinate_type ct; // Abbreviation
+ typedef boost::numeric::ublas::matrix<coordinate_type> matrix_type;
+ matrix_type m_matrix;
+
+public :
+
+ inline ublas_transformer(
+ ct const& m_0_0, ct const& m_0_1, ct const& m_0_2,
+ ct const& m_1_0, ct const& m_1_1, ct const& m_1_2,
+ ct const& m_2_0, ct const& m_2_1, ct const& m_2_2)
+ : m_matrix(3, 3)
+ {
+ m_matrix(0,0) = m_0_0; m_matrix(0,1) = m_0_1; m_matrix(0,2) = m_0_2;
+ m_matrix(1,0) = m_1_0; m_matrix(1,1) = m_1_1; m_matrix(1,2) = m_1_2;
+ m_matrix(2,0) = m_2_0; m_matrix(2,1) = m_2_1; m_matrix(2,2) = m_2_2;
+ }
+
+ inline ublas_transformer(matrix_type const& matrix)
+ : m_matrix(matrix)
+ {}
+
+
+ inline ublas_transformer() : m_matrix(3, 3) {}
+
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ assert_dimension_greater_equal<P1, 2>();
+ assert_dimension_greater_equal<P2, 2>();
+
+ coordinate_type const& c1 = get<0>(p1);
+ coordinate_type const& c2 = get<1>(p1);
+
+
+ coordinate_type p2x = c1 * m_matrix(0,0) + c2 * m_matrix(0,1) + m_matrix(0,2);
+ coordinate_type p2y = c1 * m_matrix(1,0) + c2 * m_matrix(1,1) + m_matrix(1,2);
+
+ typedef typename geometry::coordinate_type<P2>::type ct2;
+ set<0>(p2, boost::numeric_cast<ct2>(p2x));
+ set<1>(p2, boost::numeric_cast<ct2>(p2y));
+
+ return true;
+ }
+
+ matrix_type const& matrix() const { return m_matrix; }
+};
+
+
+// It IS possible to go from 3 to 2 coordinates
+template <typename P1, typename P2>
+class ublas_transformer<P1, P2, 3, 2> : public ublas_transformer<P1, P2, 2, 2>
+{
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+ typedef coordinate_type ct; // Abbreviation
+
+public :
+ inline ublas_transformer(
+ ct const& m_0_0, ct const& m_0_1, ct const& m_0_2,
+ ct const& m_1_0, ct const& m_1_1, ct const& m_1_2,
+ ct const& m_2_0, ct const& m_2_1, ct const& m_2_2)
+ : ublas_transformer<P1, P2, 2, 2>(
+ m_0_0, m_0_1, m_0_2,
+ m_1_0, m_1_1, m_1_2,
+ m_2_0, m_2_1, m_2_2)
+ {}
+
+ inline ublas_transformer()
+ : ublas_transformer<P1, P2, 2, 2>()
+ {}
+};
+
+
+template <typename P1, typename P2>
+class ublas_transformer<P1, P2, 3, 3>
+{
+protected :
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+ typedef coordinate_type ct; // Abbreviation
+ typedef boost::numeric::ublas::matrix<coordinate_type> matrix_type;
+ matrix_type m_matrix;
+
+ inline ublas_transformer(
+ ct const& m_0_0, ct const& m_0_1, ct const& m_0_2, ct const& m_0_3,
+ ct const& m_1_0, ct const& m_1_1, ct const& m_1_2, ct const& m_1_3,
+ ct const& m_2_0, ct const& m_2_1, ct const& m_2_2, ct const& m_2_3,
+ ct const& m_3_0, ct const& m_3_1, ct const& m_3_2, ct const& m_3_3
+ )
+ : m_matrix(4, 4)
+ {
+ m_matrix(0,0) = m_0_0; m_matrix(0,1) = m_0_1; m_matrix(0,2) = m_0_2; m_matrix(0,3) = m_0_3;
+ m_matrix(1,0) = m_1_0; m_matrix(1,1) = m_1_1; m_matrix(1,2) = m_1_2; m_matrix(1,3) = m_1_3;
+ m_matrix(2,0) = m_2_0; m_matrix(2,1) = m_2_1; m_matrix(2,2) = m_2_2; m_matrix(2,3) = m_2_3;
+ m_matrix(3,0) = m_3_0; m_matrix(3,1) = m_3_1; m_matrix(3,2) = m_3_2; m_matrix(3,3) = m_3_3;
+ }
+
+ inline ublas_transformer() : m_matrix(4, 4) {}
+
+public :
+
+ inline bool apply(P1 const& p1, P2& p2) const
+ {
+ coordinate_type const& c1 = get<0>(p1);
+ coordinate_type const& c2 = get<1>(p1);
+ coordinate_type const& c3 = get<2>(p1);
+
+ typedef typename geometry::coordinate_type<P2>::type ct2;
+
+ set<0>(p2, boost::numeric_cast<ct2>(
+ c1 * m_matrix(0,0) + c2 * m_matrix(0,1) + c3 * m_matrix(0,2) + m_matrix(0,3)));
+ set<1>(p2, boost::numeric_cast<ct2>(
+ c1 * m_matrix(1,0) + c2 * m_matrix(1,1) + c3 * m_matrix(1,2) + m_matrix(1,3)));
+ set<2>(p2, boost::numeric_cast<ct2>(
+ c1 * m_matrix(2,0) + c2 * m_matrix(2,1) + c3 * m_matrix(2,2) + m_matrix(2,3)));
+
+ return true;
+ }
+
+ matrix_type const& matrix() const { return m_matrix; }
+};
+
+
+/*!
+\brief Strategy of translate transformation in Cartesian system.
+\details Translate moves a geometry a fixed distance in 2 or 3 dimensions.
+\see http://en.wikipedia.org/wiki/Translation_%28geometry%29
+\ingroup strategies
+\tparam P1 first point type
+\tparam P2 second point type
+\tparam Dimension1 number of dimensions to transform from first point
+\tparam Dimension1 number of dimensions to transform to second point
+ */
+template
+<
+ typename P1, typename P2,
+ std::size_t Dimension1 = geometry::dimension<P1>::type::value,
+ std::size_t Dimension2 = geometry::dimension<P2>::type::value
+>
+class translate_transformer
+{
+};
+
+
+template <typename P1, typename P2>
+class translate_transformer<P1, P2, 2, 2> : public ublas_transformer<P1, P2, 2, 2>
+{
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+public :
+ // To have translate transformers compatible for 2/3 dimensions, the
+ // constructor takes an optional third argument doing nothing.
+ inline translate_transformer(coordinate_type const& translate_x,
+ coordinate_type const& translate_y,
+ coordinate_type const& = 0)
+ : ublas_transformer<P1, P2, 2, 2>(
+ 1, 0, translate_x,
+ 0, 1, translate_y,
+ 0, 0, 1)
+ {}
+};
+
+
+template <typename P1, typename P2>
+class translate_transformer<P1, P2, 3, 3> : public ublas_transformer<P1, P2, 3, 3>
+{
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+public :
+ inline translate_transformer(coordinate_type const& translate_x,
+ coordinate_type const& translate_y,
+ coordinate_type const& translate_z)
+ : ublas_transformer<P1, P2, 3, 3>(
+ 1, 0, 0, translate_x,
+ 0, 1, 0, translate_y,
+ 0, 0, 1, translate_z,
+ 0, 0, 0, 1)
+ {}
+
+};
+
+
+/*!
+\brief Strategy of scale transformation in Cartesian system.
+\details Scale scales a geometry up or down in all its dimensions.
+\see http://en.wikipedia.org/wiki/Scaling_%28geometry%29
+\ingroup strategies
+\tparam P1 first point type
+\tparam P2 second point type
+\tparam Dimension1 number of dimensions to transform from first point
+\tparam Dimension1 number of dimensions to transform to second point
+*/
+template
+<
+ typename P1, typename P2 = P1,
+ std::size_t Dimension1 = geometry::dimension<P1>::type::value,
+ std::size_t Dimension2 = geometry::dimension<P2>::type::value
+>
+class scale_transformer
+{
+};
+
+
+template <typename P1, typename P2>
+class scale_transformer<P1, P2, 2, 2> : public ublas_transformer<P1, P2, 2, 2>
+{
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+public :
+ inline scale_transformer(coordinate_type const& scale_x,
+ coordinate_type const& scale_y,
+ coordinate_type const& = 0)
+ : ublas_transformer<P1, P2, 2, 2>(
+ scale_x, 0, 0,
+ 0, scale_y, 0,
+ 0, 0, 1)
+ {}
+
+
+ inline scale_transformer(coordinate_type const& scale)
+ : ublas_transformer<P1, P2, 2, 2>(
+ scale, 0, 0,
+ 0, scale, 0,
+ 0, 0, 1)
+ {}
+};
+
+
+template <typename P1, typename P2>
+class scale_transformer<P1, P2, 3, 3> : public ublas_transformer<P1, P2, 3, 3>
+{
+ typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+ inline scale_transformer(coordinate_type const& scale_x,
+ coordinate_type const& scale_y,
+ coordinate_type const& scale_z)
+ : ublas_transformer<P1, P2, 3, 3>(
+ scale_x, 0, 0, 0,
+ 0, scale_y, 0, 0,
+ 0, 0, scale_z, 0,
+ 0, 0, 0, 1)
+ {}
+
+
+ inline scale_transformer(coordinate_type const& scale)
+ : ublas_transformer<P1, P2, 3, 3>(
+ scale, 0, 0, 0,
+ 0, scale, 0, 0,
+ 0, 0, scale, 0,
+ 0, 0, 0, 1)
+ {}
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename DegreeOrRadian>
+struct as_radian
+{};
+
+
+template <>
+struct as_radian<radian>
+{
+ template <typename T>
+ static inline T get(T const& value)
+ {
+ return value;
+ }
+};
+
+template <>
+struct as_radian<degree>
+{
+ template <typename T>
+ static inline T get(T const& value)
+ {
+ return value * math::d2r;
+ }
+
+};
+
+
+template
+<
+ typename P1, typename P2,
+ std::size_t Dimension1 = geometry::dimension<P1>::type::value,
+ std::size_t Dimension2 = geometry::dimension<P2>::type::value
+>
+class rad_rotate_transformer
+ : public ublas_transformer<P1, P2, Dimension1, Dimension2>
+{
+ // Angle has type of coordinate type, but at least a double
+ typedef typename select_most_precise
+ <
+ typename select_coordinate_type<P1, P2>::type,
+ double
+ >::type angle_type;
+
+public :
+ inline rad_rotate_transformer(angle_type const& angle)
+ : ublas_transformer<P1, P2, Dimension1, Dimension2>(
+ cos(angle), sin(angle), 0,
+ -sin(angle), cos(angle), 0,
+ 0, 0, 1)
+ {}
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Strategy of rotate transformation in Cartesian system.
+\details Rotate rotates a geometry of specified angle about a fixed point (e.g. origin).
+\see http://en.wikipedia.org/wiki/Rotation_%28mathematics%29
+\ingroup strategies
+\tparam P1 first point type
+\tparam P2 second point type
+\tparam DegreeOrRadian degree/or/radian, type of rotation angle specification
+\note A single angle is needed to specify a rotation in 2D.
+ Not yet in 3D, the 3D version requires special things to allow
+ for rotation around X, Y, Z or arbitrary axis.
+\todo The 3D version will not compile.
+ */
+template <typename P1, typename P2, typename DegreeOrRadian>
+class rotate_transformer : public detail::rad_rotate_transformer<P1, P2>
+{
+ // Angle has type of coordinate type, but at least a double
+ typedef typename select_most_precise
+ <
+ typename select_coordinate_type<P1, P2>::type,
+ double
+ >::type angle_type;
+
+public :
+ inline rotate_transformer(angle_type const& angle)
+ : detail::rad_rotate_transformer
+ <
+ P1, P2
+ >(detail::as_radian<DegreeOrRadian>::get(angle))
+ {}
+};
+
+
+}} // namespace strategy::transform
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
diff --git a/src/boost/geometry/strategies/within.hpp b/src/boost/geometry/strategies/within.hpp
new file mode 100644
index 0000000..0852a22
--- /dev/null
+++ b/src/boost/geometry/strategies/within.hpp
@@ -0,0 +1,71 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_WITHIN_HPP
+#define BOOST_GEOMETRY_STRATEGIES_WITHIN_HPP
+
+#include <boost/mpl/assert.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace within
+{
+
+
+namespace services
+{
+
+/*!
+\brief Traits class binding a within determination strategy to a coordinate system
+\ingroup within
+\tparam TagContained tag (possibly casted) of point-type
+\tparam TagContained tag (possibly casted) of (possibly) containing type
+\tparam CsTagContained tag of coordinate system of point-type
+\tparam CsTagContaining tag of coordinate system of (possibly) containing type
+\tparam Geometry geometry-type of input (often point, or box)
+\tparam GeometryContaining geometry-type of input (possibly) containing type
+*/
+template
+<
+ typename TagContained,
+ typename TagContaining,
+ typename CastedTagContained,
+ typename CastedTagContaining,
+ typename CsTagContained,
+ typename CsTagContaining,
+ typename GeometryContained,
+ typename GeometryContaining
+>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_TYPES
+ , (types<GeometryContained, GeometryContaining>)
+ );
+};
+
+
+} // namespace services
+
+
+}} // namespace strategy::within
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_WITHIN_HPP
+
diff --git a/src/boost/geometry/util/add_const_if_c.hpp b/src/boost/geometry/util/add_const_if_c.hpp
new file mode 100644
index 0000000..9e0c012
--- /dev/null
+++ b/src/boost/geometry/util/add_const_if_c.hpp
@@ -0,0 +1,56 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_ADD_CONST_IF_C_HPP
+#define BOOST_GEOMETRY_UTIL_ADD_CONST_IF_C_HPP
+
+
+#include <boost/mpl/if.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+ \brief Meta-function to define a const or non const type
+ \ingroup utility
+ \details If the boolean template parameter is true, the type parameter
+ will be defined as const, otherwise it will be defined as it was.
+ This meta-function is used to have one implementation for both
+ const and non const references
+ \note This traits class is completely independant from Boost.Geometry
+ and might be a separate addition to Boost
+ \note Used in a.o. for_each, interior_rings, exterior_ring
+ \par Example
+ \code
+ void foo(typename add_const_if_c<IsConst, Point>::type& point)
+ \endcode
+*/
+template <bool IsConst, typename Type>
+struct add_const_if_c
+{
+ typedef typename boost::mpl::if_c
+ <
+ IsConst,
+ Type const,
+ Type
+ >::type type;
+};
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_ADD_CONST_IF_C_HPP
diff --git a/src/boost/geometry/util/calculation_type.hpp b/src/boost/geometry/util/calculation_type.hpp
new file mode 100644
index 0000000..aef5890
--- /dev/null
+++ b/src/boost/geometry/util/calculation_type.hpp
@@ -0,0 +1,176 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2012 Mateusz Loskot, London, UK.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP
+#define BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP
+
+#include <boost/config.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace util
+{
+
+namespace detail
+{
+
+struct default_integral
+{
+#ifdef BOOST_HAS_LONG_LONG
+ typedef boost::long_long_type type;
+#else
+ typedef int type;
+#endif
+};
+
+/*!
+\details Selects the most appropriate:
+ - if calculation type is specified (not void), that one is used
+ - else if type is non-fundamental (user defined e.g. ttmath), that one
+ - else if type is floating point, the specified default FP is used
+ - else it is integral and the specified default integral is used
+ */
+template
+<
+ typename Type,
+ typename CalculationType,
+ typename DefaultFloatingPointCalculationType,
+ typename DefaultIntegralCalculationType
+>
+struct calculation_type
+{
+ BOOST_STATIC_ASSERT((
+ boost::is_fundamental
+ <
+ DefaultFloatingPointCalculationType
+ >::type::value
+ ));
+ BOOST_STATIC_ASSERT((
+ boost::is_fundamental
+ <
+ DefaultIntegralCalculationType
+ >::type::value
+ ));
+
+
+ typedef typename boost::mpl::if_
+ <
+ boost::is_void<CalculationType>,
+ typename boost::mpl::if_
+ <
+ boost::is_floating_point<Type>,
+ typename select_most_precise
+ <
+ DefaultFloatingPointCalculationType,
+ Type
+ >::type,
+ typename select_most_precise
+ <
+ DefaultIntegralCalculationType,
+ Type
+ >::type
+ >::type,
+ CalculationType
+ >::type type;
+};
+
+} // namespace detail
+
+
+namespace calculation_type
+{
+
+namespace geometric
+{
+
+template
+<
+ typename Geometry,
+ typename CalculationType,
+ typename DefaultFloatingPointCalculationType = double,
+ typename DefaultIntegralCalculationType = detail::default_integral::type
+>
+struct unary
+{
+ typedef typename detail::calculation_type
+ <
+ typename geometry::coordinate_type<Geometry>::type,
+ CalculationType,
+ DefaultFloatingPointCalculationType,
+ DefaultIntegralCalculationType
+ >::type type;
+};
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename CalculationType,
+ typename DefaultFloatingPointCalculationType = double,
+ typename DefaultIntegralCalculationType = detail::default_integral::type
+>
+struct binary
+{
+ typedef typename detail::calculation_type
+ <
+ typename select_coordinate_type<Geometry1, Geometry2>::type,
+ CalculationType,
+ DefaultFloatingPointCalculationType,
+ DefaultIntegralCalculationType
+ >::type type;
+};
+
+
+/*!
+\brief calculation type (ternary, for three geometry types)
+ */
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Geometry3,
+ typename CalculationType,
+ typename DefaultFloatingPointCalculationType = double,
+ typename DefaultIntegralCalculationType = detail::default_integral::type
+>
+struct ternary
+{
+ typedef typename detail::calculation_type
+ <
+ typename select_most_precise
+ <
+ typename coordinate_type<Geometry1>::type,
+ typename select_coordinate_type
+ <
+ Geometry2,
+ Geometry3
+ >::type
+ >::type,
+ CalculationType,
+ DefaultFloatingPointCalculationType,
+ DefaultIntegralCalculationType
+ >::type type;
+};
+
+}} // namespace calculation_type::geometric
+
+} // namespace util
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP
diff --git a/src/boost/geometry/util/closure_as_bool.hpp b/src/boost/geometry/util/closure_as_bool.hpp
new file mode 100644
index 0000000..57fcd52
--- /dev/null
+++ b/src/boost/geometry/util/closure_as_bool.hpp
@@ -0,0 +1,46 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_CLOSURE_AS_BOOL_HPP
+#define BOOST_GEOMETRY_UTIL_CLOSURE_AS_BOOL_HPP
+
+#include <boost/geometry/core/closure.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+template<closure_selector Closure>
+struct closure_as_bool
+{};
+
+
+template<>
+struct closure_as_bool<closed>
+{
+ static const bool value = true;
+};
+
+
+template<>
+struct closure_as_bool<open>
+{
+ static const bool value = false;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_CLOSURE_AS_BOOL_HPP
diff --git a/src/boost/geometry/util/coordinate_cast.hpp b/src/boost/geometry/util/coordinate_cast.hpp
new file mode 100644
index 0000000..16a15cc
--- /dev/null
+++ b/src/boost/geometry/util/coordinate_cast.hpp
@@ -0,0 +1,55 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_COORDINATE_CAST_HPP
+#define BOOST_GEOMETRY_UTIL_COORDINATE_CAST_HPP
+
+#include <cstdlib>
+#include <string>
+#include <boost/lexical_cast.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+/*!
+\brief cast coordinates from a string to a coordinate type
+\detail By default it uses lexical_cast. However, lexical_cast seems not to support
+ ttmath / partial specializations. Therefore this small utility is added.
+ See also "define_pi" where the same issue is solved
+*/
+template <typename CoordinateType>
+struct coordinate_cast
+{
+ static inline CoordinateType apply(std::string const& source)
+ {
+#if defined(BOOST_GEOMETRY_NO_LEXICAL_CAST)
+ return atof(source.c_str());
+#else
+ return boost::lexical_cast<CoordinateType>(source);
+#endif
+ }
+};
+
+
+} // namespace detail
+#endif
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_COORDINATE_CAST_HPP
diff --git a/src/boost/geometry/util/for_each_coordinate.hpp b/src/boost/geometry/util/for_each_coordinate.hpp
new file mode 100644
index 0000000..7a1f55b
--- /dev/null
+++ b/src/boost/geometry/util/for_each_coordinate.hpp
@@ -0,0 +1,94 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_FOR_EACH_COORDINATE_HPP
+#define BOOST_GEOMETRY_UTIL_FOR_EACH_COORDINATE_HPP
+
+#include <boost/concept/requires.hpp>
+#include <boost/geometry/geometries/concepts/point_concept.hpp>
+#include <boost/geometry/util/add_const_if_c.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Point, int Dimension, int DimensionCount, bool IsConst>
+struct coordinates_scanner
+{
+ template <typename Op>
+ static inline Op apply(typename add_const_if_c
+ <
+ IsConst,
+ Point
+ >::type& point, Op operation)
+ {
+ operation.template apply<Point, Dimension>(point);
+ return coordinates_scanner
+ <
+ Point,
+ Dimension+1,
+ DimensionCount,
+ IsConst
+ >::apply(point, operation);
+ }
+};
+
+template <typename Point, int DimensionCount, bool IsConst>
+struct coordinates_scanner<Point, DimensionCount, DimensionCount, IsConst>
+{
+ template <typename Op>
+ static inline Op apply(typename add_const_if_c
+ <
+ IsConst,
+ Point
+ >::type& , Op operation)
+ {
+ return operation;
+ }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+template <typename Point, typename Op>
+inline void for_each_coordinate(Point& point, Op operation)
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+ typedef typename detail::coordinates_scanner
+ <
+ Point, 0, dimension<Point>::type::value, false
+ > scanner;
+
+ scanner::apply(point, operation);
+}
+
+template <typename Point, typename Op>
+inline Op for_each_coordinate(Point const& point, Op operation)
+{
+ BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point>) );
+
+ typedef typename detail::coordinates_scanner
+ <
+ Point, 0, dimension<Point>::type::value, true
+ > scanner;
+
+ return scanner::apply(point, operation);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_FOR_EACH_COORDINATE_HPP
diff --git a/src/boost/geometry/util/math.hpp b/src/boost/geometry/util/math.hpp
new file mode 100644
index 0000000..95cbdf2
--- /dev/null
+++ b/src/boost/geometry/util/math.hpp
@@ -0,0 +1,222 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_MATH_HPP
+#define BOOST_GEOMETRY_UTIL_MATH_HPP
+
+#include <cmath>
+#include <limits>
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/geometry/util/select_most_precise.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace math
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template <typename Type, bool IsFloatingPoint>
+struct equals
+{
+ static inline bool apply(Type const& a, Type const& b)
+ {
+ return a == b;
+ }
+};
+
+template <typename Type>
+struct equals<Type, true>
+{
+ static inline Type get_max(Type const& a, Type const& b, Type const& c)
+ {
+ return (std::max)((std::max)(a, b), c);
+ }
+
+ static inline bool apply(Type const& a, Type const& b)
+ {
+ if (a == b)
+ {
+ return true;
+ }
+
+ // See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17,
+ // FUTURE: replace by some boost tool or boost::test::close_at_tolerance
+ return std::abs(a - b) <= std::numeric_limits<Type>::epsilon() * get_max(std::abs(a), std::abs(b), 1.0);
+ }
+};
+
+template <typename Type, bool IsFloatingPoint>
+struct smaller
+{
+ static inline bool apply(Type const& a, Type const& b)
+ {
+ return a < b;
+ }
+};
+
+template <typename Type>
+struct smaller<Type, true>
+{
+ static inline bool apply(Type const& a, Type const& b)
+ {
+ if (equals<Type, true>::apply(a, b))
+ {
+ return false;
+ }
+ return a < b;
+ }
+};
+
+
+template <typename Type, bool IsFloatingPoint>
+struct equals_with_epsilon : public equals<Type, IsFloatingPoint> {};
+
+
+/*!
+\brief Short construct to enable partial specialization for PI, currently not possible in Math.
+*/
+template <typename T>
+struct define_pi
+{
+ static inline T apply()
+ {
+ // Default calls Boost.Math
+ return boost::math::constants::pi<T>();
+ }
+};
+
+
+} // namespace detail
+#endif
+
+
+template <typename T>
+inline T pi() { return detail::define_pi<T>::apply(); }
+
+
+// Maybe replace this by boost equals or boost ublas numeric equals or so
+
+/*!
+ \brief returns true if both arguments are equal.
+ \ingroup utility
+ \param a first argument
+ \param b second argument
+ \return true if a == b
+ \note If both a and b are of an integral type, comparison is done by ==.
+ If one of the types is floating point, comparison is done by abs and
+ comparing with epsilon. If one of the types is non-fundamental, it might
+ be a high-precision number and comparison is done using the == operator
+ of that class.
+*/
+
+template <typename T1, typename T2>
+inline bool equals(T1 const& a, T2 const& b)
+{
+ typedef typename select_most_precise<T1, T2>::type select_type;
+ return detail::equals
+ <
+ select_type,
+ boost::is_floating_point<select_type>::type::value
+ >::apply(a, b);
+}
+
+template <typename T1, typename T2>
+inline bool equals_with_epsilon(T1 const& a, T2 const& b)
+{
+ typedef typename select_most_precise<T1, T2>::type select_type;
+ return detail::equals_with_epsilon
+ <
+ select_type,
+ boost::is_floating_point<select_type>::type::value
+ >::apply(a, b);
+}
+
+template <typename T1, typename T2>
+inline bool smaller(T1 const& a, T2 const& b)
+{
+ typedef typename select_most_precise<T1, T2>::type select_type;
+ return detail::smaller
+ <
+ select_type,
+ boost::is_floating_point<select_type>::type::value
+ >::apply(a, b);
+}
+
+template <typename T1, typename T2>
+inline bool larger(T1 const& a, T2 const& b)
+{
+ typedef typename select_most_precise<T1, T2>::type select_type;
+ return detail::smaller
+ <
+ select_type,
+ boost::is_floating_point<select_type>::type::value
+ >::apply(b, a);
+}
+
+
+
+double const d2r = geometry::math::pi<double>() / 180.0;
+double const r2d = 1.0 / d2r;
+
+/*!
+ \brief Calculates the haversine of an angle
+ \ingroup utility
+ \note See http://en.wikipedia.org/wiki/Haversine_formula
+ haversin(alpha) = sin2(alpha/2)
+*/
+template <typename T>
+inline T hav(T const& theta)
+{
+ T const half = T(0.5);
+ T const sn = sin(half * theta);
+ return sn * sn;
+}
+
+/*!
+\brief Short utility to return the square
+\ingroup utility
+\param value Value to calculate the square from
+\return The squared value
+*/
+template <typename T>
+inline T sqr(T const& value)
+{
+ return value * value;
+}
+
+
+/*!
+\brief Short utility to workaround gcc/clang problem that abs is converting to integer
+\ingroup utility
+*/
+template<typename T>
+inline T abs(const T& t)
+{
+ using std::abs;
+ return abs(t);
+}
+
+
+} // namespace math
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_MATH_HPP
diff --git a/src/boost/geometry/util/order_as_direction.hpp b/src/boost/geometry/util/order_as_direction.hpp
new file mode 100644
index 0000000..6895ebf
--- /dev/null
+++ b/src/boost/geometry/util/order_as_direction.hpp
@@ -0,0 +1,46 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_ORDER_AS_DIRECTION_HPP
+#define BOOST_GEOMETRY_UTIL_ORDER_AS_DIRECTION_HPP
+
+#include <boost/geometry/core/point_order.hpp>
+#include <boost/geometry/views/reversible_view.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+template<order_selector Order>
+struct order_as_direction
+{};
+
+
+template<>
+struct order_as_direction<clockwise>
+{
+ static const iterate_direction value = iterate_forward;
+};
+
+
+template<>
+struct order_as_direction<counterclockwise>
+{
+ static const iterate_direction value = iterate_reverse;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_ORDER_AS_DIRECTION_HPP
diff --git a/src/boost/geometry/util/parameter_type_of.hpp b/src/boost/geometry/util/parameter_type_of.hpp
new file mode 100644
index 0000000..b8872d5
--- /dev/null
+++ b/src/boost/geometry/util/parameter_type_of.hpp
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
+#define BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
+
+
+#include <boost/function_types/function_arity.hpp>
+#include <boost/function_types/is_member_function_pointer.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/plus.hpp>
+#include <boost/type_traits.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief Meta-function selecting a parameter type of a (member) function, by index
+\ingroup utility
+ */
+template <typename Method, std::size_t Index>
+struct parameter_type_of
+{
+ typedef typename boost::function_types::parameter_types
+ <
+ Method
+ >::type parameter_types;
+
+ typedef typename boost::mpl::if_
+ <
+ boost::function_types::is_member_function_pointer<Method>,
+ boost::mpl::int_<1>,
+ boost::mpl::int_<0>
+ >::type base_index_type;
+
+ typedef typename boost::mpl::if_c
+ <
+ Index == 0,
+ base_index_type,
+ typename boost::mpl::plus
+ <
+ base_index_type,
+ boost::mpl::int_<Index>
+ >::type
+ >::type indexed_type;
+
+ typedef typename boost::remove_reference
+ <
+ typename boost::mpl::at
+ <
+ parameter_types,
+ indexed_type
+ >::type
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
diff --git a/src/boost/geometry/util/promote_floating_point.hpp b/src/boost/geometry/util/promote_floating_point.hpp
new file mode 100644
index 0000000..0c74cb8
--- /dev/null
+++ b/src/boost/geometry/util/promote_floating_point.hpp
@@ -0,0 +1,50 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
+#define BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+ \brief Meta-function converting, if necessary, to "a floating point" type
+ \details
+ - if input type is integer, type is double
+ - else type is input type
+ \ingroup utility
+ */
+
+template <typename T, typename PromoteIntegerTo = double>
+struct promote_floating_point
+{
+ typedef typename
+ boost::mpl::if_
+ <
+ boost::is_integral<T>,
+ PromoteIntegerTo,
+ T
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
diff --git a/src/boost/geometry/util/rational.hpp b/src/boost/geometry/util/rational.hpp
new file mode 100644
index 0000000..45bee20
--- /dev/null
+++ b/src/boost/geometry/util/rational.hpp
@@ -0,0 +1,179 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2011-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2011-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_RATIONAL_HPP
+#define BOOST_GEOMETRY_UTIL_RATIONAL_HPP
+
+#include <boost/rational.hpp>
+#include <boost/numeric/conversion/bounds.hpp>
+
+#include <boost/geometry/util/coordinate_cast.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost{ namespace geometry
+{
+
+
+// Specialize for Boost.Geometry's coordinate cast
+// (from string to coordinate type)
+namespace detail
+{
+
+template <typename T>
+struct coordinate_cast<rational<T> >
+{
+ static inline void split_parts(std::string const& source, std::string::size_type p,
+ T& before, T& after, bool& negate, std::string::size_type& len)
+ {
+ std::string before_part = source.substr(0, p);
+ std::string const after_part = source.substr(p + 1);
+
+ negate = false;
+
+ if (before_part.size() > 0 && before_part[0] == '-')
+ {
+ negate = true;
+ before_part.erase(0, 1);
+ }
+ before = atol(before_part.c_str());
+ after = atol(after_part.c_str());
+ len = after_part.length();
+ }
+
+
+ static inline rational<T> apply(std::string const& source)
+ {
+ T before, after;
+ bool negate;
+ std::string::size_type len;
+
+ // Note: decimal comma is not (yet) supported, it does (and should) not
+ // occur in a WKT, where points are comma separated.
+ std::string::size_type p = source.find(".");
+ if (p == std::string::npos)
+ {
+ p = source.find("/");
+ if (p == std::string::npos)
+ {
+ return rational<T>(atol(source.c_str()));
+ }
+ split_parts(source, p, before, after, negate, len);
+
+ return negate
+ ? -rational<T>(before, after)
+ : rational<T>(before, after)
+ ;
+
+ }
+
+ split_parts(source, p, before, after, negate, len);
+
+ T den = 1;
+ for (std::string::size_type i = 0; i < len; i++)
+ {
+ den *= 10;
+ }
+
+ return negate
+ ? -rational<T>(before) - rational<T>(after, den)
+ : rational<T>(before) + rational<T>(after, den)
+ ;
+ }
+};
+
+} // namespace detail
+
+// Specialize for Boost.Geometry's select_most_precise
+template <typename T1, typename T2>
+struct select_most_precise<boost::rational<T1>, boost::rational<T2> >
+{
+ typedef typename boost::rational
+ <
+ typename select_most_precise<T1, T2>::type
+ > type;
+};
+
+template <typename T>
+struct select_most_precise<boost::rational<T>, double>
+{
+ typedef typename boost::rational<T> type;
+};
+
+
+}} // namespace boost::geometry
+
+
+// Specializes boost::rational to boost::numeric::bounds
+namespace boost { namespace numeric
+{
+
+template<class T>
+struct bounds<rational<T> >
+{
+ static inline rational<T> lowest()
+ {
+ return rational<T>(bounds<T>::lowest(), 1);
+ }
+ static inline rational<T> highest()
+ {
+ return rational<T>(bounds<T>::highest(), 1);
+ }
+};
+
+}} // namespace boost::numeric
+
+
+// Support for boost::numeric_cast to int and to double (necessary for SVG-mapper)
+namespace boost { namespace numeric
+{
+
+template
+<
+ typename T,
+ typename Traits,
+ typename OverflowHandler,
+ typename Float2IntRounder,
+ typename RawConverter,
+ typename UserRangeChecker
+>
+struct converter<int, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
+{
+ static inline int convert(rational<T> const& arg)
+ {
+ return int(rational_cast<double>(arg));
+ }
+};
+
+template
+<
+ typename T,
+ typename Traits,
+ typename OverflowHandler,
+ typename Float2IntRounder,
+ typename RawConverter,
+ typename UserRangeChecker
+>
+struct converter<double, rational<T>, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker>
+{
+ static inline double convert(rational<T> const& arg)
+ {
+ return rational_cast<double>(arg);
+ }
+};
+
+
+}}
+
+
+#endif // BOOST_GEOMETRY_UTIL_RATIONAL_HPP
diff --git a/src/boost/geometry/util/readme.txt b/src/boost/geometry/util/readme.txt
new file mode 100644
index 0000000..7a1bf88
--- /dev/null
+++ b/src/boost/geometry/util/readme.txt
@@ -0,0 +1,17 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+This folder contains several headerfiles not fitting in one of the other folders,
+or meta-functions which would fit into boost as a separate trait or utility,
+such as add_const_if_c
+
diff --git a/src/boost/geometry/util/select_calculation_type.hpp b/src/boost/geometry/util/select_calculation_type.hpp
new file mode 100644
index 0000000..4946c45
--- /dev/null
+++ b/src/boost/geometry/util/select_calculation_type.hpp
@@ -0,0 +1,57 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_SELECT_CALCULATION_TYPE_HPP
+#define BOOST_GEOMETRY_UTIL_SELECT_CALCULATION_TYPE_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/util/select_coordinate_type.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+ \brief Meta-function selecting the "calculation" type
+ \details Based on two input geometry types, and an input calculation type,
+ (which defaults to void in the calling function), this meta-function
+ selects the most appropriate:
+ - if calculation type is specified, that one is used,
+ - if it is void, the most precise of the two points is used
+ \ingroup utility
+ */
+template <typename Geometry1, typename Geometry2, typename CalculationType>
+struct select_calculation_type
+{
+ typedef typename
+ boost::mpl::if_
+ <
+ boost::is_void<CalculationType>,
+ typename select_coordinate_type
+ <
+ Geometry1,
+ Geometry2
+ >::type,
+ CalculationType
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_SELECT_CALCULATION_TYPE_HPP
diff --git a/src/boost/geometry/util/select_coordinate_type.hpp b/src/boost/geometry/util/select_coordinate_type.hpp
new file mode 100644
index 0000000..8309da4
--- /dev/null
+++ b/src/boost/geometry/util/select_coordinate_type.hpp
@@ -0,0 +1,45 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_SELECT_COORDINATE_TYPE_HPP
+#define BOOST_GEOMETRY_UTIL_SELECT_COORDINATE_TYPE_HPP
+
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+ \brief Meta-function selecting the most precise coordinate type
+ of two geometries
+ \ingroup utility
+ */
+template <typename T1, typename T2>
+struct select_coordinate_type
+{
+ typedef typename select_most_precise
+ <
+ typename coordinate_type<T1>::type,
+ typename coordinate_type<T2>::type
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_SELECT_COORDINATE_TYPE_HPP
diff --git a/src/boost/geometry/util/select_most_precise.hpp b/src/boost/geometry/util/select_most_precise.hpp
new file mode 100644
index 0000000..d55fdbf
--- /dev/null
+++ b/src/boost/geometry/util/select_most_precise.hpp
@@ -0,0 +1,162 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
+#define BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+
+namespace detail { namespace select_most_precise
+{
+
+
+// At least one of the types is non-fundamental. Take that one.
+// if both are non-fundamental, the type-to-be-selected
+// is unknown, it should be defined by explicit specialization.
+template <bool Fundamental1, bool Fundamental2, typename T1, typename T2>
+struct select_non_fundamental
+{
+ typedef T1 type;
+};
+
+template <typename T1, typename T2>
+struct select_non_fundamental<true, false, T1, T2>
+{
+ typedef T2 type;
+};
+
+template <typename T1, typename T2>
+struct select_non_fundamental<false, true, T1, T2>
+{
+ typedef T1 type;
+};
+
+
+// Selection of largest type (e.g. int of <short int,int>
+// It defaults takes the first one, if second is larger, take the second one
+template <bool SecondLarger, typename T1, typename T2>
+struct select_largest
+{
+ typedef T1 type;
+};
+
+template <typename T1, typename T2>
+struct select_largest<true, T1, T2>
+{
+ typedef T2 type;
+};
+
+
+
+// Selection of floating point and specializations:
+// both FP or both !FP does never occur...
+template <bool FP1, bool FP2, typename T1, typename T2>
+struct select_floating_point
+{
+ typedef char type;
+};
+
+
+// ... so if ONE but not both of these types is floating point, take that one
+template <typename T1, typename T2>
+struct select_floating_point<true, false, T1, T2>
+{
+ typedef T1 type;
+};
+
+
+template <typename T1, typename T2>
+struct select_floating_point<false, true, T1, T2>
+{
+ typedef T2 type;
+};
+
+
+}} // namespace detail::select_most_precise
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+ \brief Meta-function to select, of two types, the most accurate type for
+ calculations
+ \ingroup utility
+ \details select_most_precise classes, compares two types on compile time.
+ For example, if an addition must be done with a double and an integer, the
+ result must be a double.
+ If both types are integer, the result can be an integer.
+ \note It is different from the "promote" class, already in boost. That
+ class promotes e.g. a (one) float to a double. This class selects a
+ type from two types. It takes the most accurate, but does not promote
+ afterwards.
+ \note This traits class is completely independant from GGL and might be a
+ separate addition to Boost
+ \note If the input is a non-fundamental type, it might be a calculation
+ type such as a GMP-value or another high precision value. Therefore,
+ if one is non-fundamental, that one is chosen.
+ \note If both types are non-fundamental, the result is indeterminate and
+ currently the first one is chosen.
+*/
+template <typename T1, typename T2>
+struct select_most_precise
+{
+ static const bool second_larger = sizeof(T2) > sizeof(T1);
+ static const bool one_not_fundamental = !
+ (boost::is_fundamental<T1>::type::value
+ && boost::is_fundamental<T2>::type::value);
+
+ static const bool both_same =
+ boost::is_floating_point<T1>::type::value
+ == boost::is_floating_point<T2>::type::value;
+
+ typedef typename boost::mpl::if_c
+ <
+ one_not_fundamental,
+ typename detail::select_most_precise::select_non_fundamental
+ <
+ boost::is_fundamental<T1>::type::value,
+ boost::is_fundamental<T2>::type::value,
+ T1,
+ T2
+ >::type,
+ typename boost::mpl::if_c
+ <
+ both_same,
+ typename detail::select_most_precise::select_largest
+ <
+ second_larger,
+ T1,
+ T2
+ >::type,
+ typename detail::select_most_precise::select_floating_point
+ <
+ boost::is_floating_point<T1>::type::value,
+ boost::is_floating_point<T2>::type::value,
+ T1,
+ T2
+ >::type
+ >::type
+ >::type type;
+};
+
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
diff --git a/src/boost/geometry/util/write_dsv.hpp b/src/boost/geometry/util/write_dsv.hpp
new file mode 100644
index 0000000..3fef63e
--- /dev/null
+++ b/src/boost/geometry/util/write_dsv.hpp
@@ -0,0 +1,396 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_WRITE_DSV_HPP
+#define BOOST_GEOMETRY_UTIL_WRITE_DSV_HPP
+
+
+#include <cstddef>
+#include <ostream>
+#include <string>
+
+#include <boost/concept_check.hpp>
+#include <boost/range.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/core/exterior_ring.hpp>
+#include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+
+#include <boost/geometry/geometries/concepts/check.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv
+{
+
+
+struct dsv_settings
+{
+ std::string coordinate_separator;
+ std::string point_open;
+ std::string point_close;
+ std::string point_separator;
+ std::string list_open;
+ std::string list_close;
+ std::string list_separator;
+
+ dsv_settings(std::string const& sep
+ , std::string const& open
+ , std::string const& close
+ , std::string const& psep
+ , std::string const& lopen
+ , std::string const& lclose
+ , std::string const& lsep
+ )
+ : coordinate_separator(sep)
+ , point_open(open)
+ , point_close(close)
+ , point_separator(psep)
+ , list_open(lopen)
+ , list_close(lclose)
+ , list_separator(lsep)
+ {}
+};
+
+/*!
+\brief Stream coordinate of a point as \ref DSV
+*/
+template <typename Point, std::size_t Dimension, std::size_t Count>
+struct stream_coordinate
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Point const& point,
+ dsv_settings const& settings)
+ {
+ os << (Dimension > 0 ? settings.coordinate_separator : "")
+ << get<Dimension>(point);
+
+ stream_coordinate
+ <
+ Point, Dimension + 1, Count
+ >::apply(os, point, settings);
+ }
+};
+
+template <typename Point, std::size_t Count>
+struct stream_coordinate<Point, Count, Count>
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>&,
+ Point const&,
+ dsv_settings const& )
+ {
+ }
+};
+
+
+/*!
+\brief Stream indexed coordinate of a box/segment as \ref DSV
+*/
+template
+<
+ typename Geometry,
+ std::size_t Index,
+ std::size_t Dimension,
+ std::size_t Count
+>
+struct stream_indexed
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Geometry const& geometry,
+ dsv_settings const& settings)
+ {
+ os << (Dimension > 0 ? settings.coordinate_separator : "")
+ << get<Index, Dimension>(geometry);
+ stream_indexed
+ <
+ Geometry, Index, Dimension + 1, Count
+ >::apply(os, geometry, settings);
+ }
+};
+
+template <typename Geometry, std::size_t Index, std::size_t Count>
+struct stream_indexed<Geometry, Index, Count, Count>
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>&, Geometry const&,
+ dsv_settings const& )
+ {
+ }
+};
+
+
+
+/*!
+\brief Stream points as \ref DSV
+*/
+template <typename Point>
+struct dsv_point
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Point const& p,
+ dsv_settings const& settings)
+ {
+ os << settings.point_open;
+ stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p, settings);
+ os << settings.point_close;
+ }
+};
+
+/*!
+\brief Stream ranges as DSV
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename Range>
+struct dsv_range
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Range const& range,
+ dsv_settings const& settings)
+ {
+ typedef typename boost::range_iterator<Range const>::type iterator_type;
+
+ bool first = true;
+
+ os << settings.list_open;
+
+ for (iterator_type it = boost::begin(range);
+ it != boost::end(range);
+ ++it)
+ {
+ os << (first ? "" : settings.point_separator)
+ << settings.point_open;
+
+ stream_coordinate
+ <
+ point_type, 0, dimension<point_type>::type::value
+ >::apply(os, *it, settings);
+ os << settings.point_close;
+
+ first = false;
+ }
+
+ os << settings.list_close;
+ }
+
+private:
+ typedef typename boost::range_value<Range>::type point_type;
+};
+
+/*!
+\brief Stream sequence of points as DSV-part, e.g. (1 2),(3 4)
+\note Used in polygon, all multi-geometries
+*/
+
+
+template <typename Polygon>
+struct dsv_poly
+{
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Polygon const& poly,
+ dsv_settings const& settings)
+ {
+ typedef typename ring_type<Polygon>::type ring;
+
+ os << settings.list_open;
+
+ dsv_range<ring>::apply(os, exterior_ring(poly), settings);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(poly);
+ for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ os << settings.list_separator;
+ dsv_range<ring>::apply(os, *it, settings);
+ }
+ os << settings.list_close;
+ }
+};
+
+template <typename Geometry, std::size_t Index>
+struct dsv_per_index
+{
+ typedef typename point_type<Geometry>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Geometry const& geometry,
+ dsv_settings const& settings)
+ {
+ os << settings.point_open;
+ stream_indexed
+ <
+ Geometry, Index, 0, dimension<Geometry>::type::value
+ >::apply(os, geometry, settings);
+ os << settings.point_close;
+ }
+};
+
+
+template <typename Geometry>
+struct dsv_indexed
+{
+ typedef typename point_type<Geometry>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Geometry const& geometry,
+ dsv_settings const& settings)
+ {
+ os << settings.list_open;
+ dsv_per_index<Geometry, 0>::apply(os, geometry, settings);
+ os << settings.point_separator;
+ dsv_per_index<Geometry, 1>::apply(os, geometry, settings);
+ os << settings.list_close;
+ }
+};
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct dsv {};
+
+
+template <typename Point>
+struct dsv<point_tag, Point>
+ : detail::dsv::dsv_point<Point>
+{};
+
+
+template <typename Linestring>
+struct dsv<linestring_tag, Linestring>
+ : detail::dsv::dsv_range<Linestring>
+{};
+
+
+template <typename Box>
+struct dsv<box_tag, Box>
+ : detail::dsv::dsv_indexed<Box>
+{};
+
+template <typename Segment>
+struct dsv<segment_tag, Segment>
+ : detail::dsv::dsv_indexed<Segment>
+{};
+
+
+template <typename Ring>
+struct dsv<ring_tag, Ring>
+ : detail::dsv::dsv_range<Ring>
+{};
+
+
+template <typename Polygon>
+struct dsv<polygon_tag, Polygon>
+ : detail::dsv::dsv_poly<Polygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv
+{
+
+
+// FIXME: This class is not copyable/assignable but it is used as such --mloskot
+template <typename Geometry>
+class dsv_manipulator
+{
+public:
+
+ inline dsv_manipulator(Geometry const& g,
+ dsv_settings const& settings)
+ : m_geometry(g)
+ , m_settings(settings)
+ {}
+
+ template <typename Char, typename Traits>
+ inline friend std::basic_ostream<Char, Traits>& operator<<(
+ std::basic_ostream<Char, Traits>& os,
+ dsv_manipulator const& m)
+ {
+ dispatch::dsv
+ <
+ typename tag_cast
+ <
+ typename tag<Geometry>::type,
+ multi_tag
+ >::type,
+ Geometry
+ >::apply(os, m.m_geometry, m.m_settings);
+ os.flush();
+ return os;
+ }
+
+private:
+ Geometry const& m_geometry;
+ dsv_settings m_settings;
+};
+
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Main DSV-streaming function
+\details DSV stands for Delimiter Separated Values. Geometries can be streamed
+ as DSV. There are defaults for all separators.
+\note Useful for examples and testing purposes
+\note With this function GeoJSON objects can be created, using the right
+ delimiters
+\ingroup utility
+*/
+template <typename Geometry>
+inline detail::dsv::dsv_manipulator<Geometry> dsv(Geometry const& geometry
+ , std::string const& coordinate_separator = ", "
+ , std::string const& point_open = "("
+ , std::string const& point_close = ")"
+ , std::string const& point_separator = ", "
+ , std::string const& list_open = "("
+ , std::string const& list_close = ")"
+ , std::string const& list_separator = ", "
+ )
+{
+ concept::check<Geometry const>();
+
+ return detail::dsv::dsv_manipulator<Geometry>(geometry,
+ detail::dsv::dsv_settings(coordinate_separator,
+ point_open, point_close, point_separator,
+ list_open, list_close, list_separator));
+}
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_WRITE_DSV_HPP
diff --git a/src/boost/geometry/views/box_view.hpp b/src/boost/geometry/views/box_view.hpp
new file mode 100644
index 0000000..26608b0
--- /dev/null
+++ b/src/boost/geometry/views/box_view.hpp
@@ -0,0 +1,114 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_BOX_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_BOX_VIEW_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/views/detail/points_view.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief Makes a box behave like a ring or a range
+\details Adapts a box to the Boost.Range concept, enabling the user to iterating
+ box corners. The box_view is registered as a Ring Concept
+\tparam Box \tparam_geometry{Box}
+\tparam Clockwise If true, walks in clockwise direction, otherwise
+ it walks in counterclockwise direction
+\ingroup views
+
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_ring Ring Concept]
+}
+
+\qbk{[include reference/views/box_view.qbk]}
+*/
+template <typename Box, bool Clockwise = true>
+struct box_view
+ : public detail::points_view
+ <
+ typename geometry::point_type<Box>::type,
+ 5
+ >
+{
+ typedef typename geometry::point_type<Box>::type point_type;
+
+ /// Constructor accepting the box to adapt
+ explicit box_view(Box const& box)
+ : detail::points_view<point_type, 5>(copy_policy(box))
+ {}
+
+private :
+
+ class copy_policy
+ {
+ public :
+ inline copy_policy(Box const& box)
+ : m_box(box)
+ {}
+
+ inline void apply(point_type* points) const
+ {
+ detail::assign_box_corners_oriented<!Clockwise>(m_box, points);
+ points[4] = points[0];
+ }
+ private :
+ Box const& m_box;
+ };
+
+};
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+// All views on boxes are handled as rings
+namespace traits
+{
+
+template<typename Box, bool Clockwise>
+struct tag<box_view<Box, Clockwise> >
+{
+ typedef ring_tag type;
+};
+
+template<typename Box>
+struct point_order<box_view<Box, false> >
+{
+ static order_selector const value = counterclockwise;
+};
+
+
+template<typename Box>
+struct point_order<box_view<Box, true> >
+{
+ static order_selector const value = clockwise;
+};
+
+}
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_BOX_VIEW_HPP
diff --git a/src/boost/geometry/views/closeable_view.hpp b/src/boost/geometry/views/closeable_view.hpp
new file mode 100644
index 0000000..376246d
--- /dev/null
+++ b/src/boost/geometry/views/closeable_view.hpp
@@ -0,0 +1,100 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_CLOSEABLE_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_CLOSEABLE_VIEW_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/closure.hpp>
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+#include <boost/geometry/iterators/closing_iterator.hpp>
+
+#include <boost/geometry/views/identity_view.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+
+namespace detail
+{
+
+template <typename Range>
+struct closing_view
+{
+ // Keep this explicit, important for nested views/ranges
+ explicit inline closing_view(Range& r)
+ : m_range(r)
+ {}
+
+ typedef closing_iterator<Range> iterator;
+ typedef closing_iterator<Range const> const_iterator;
+
+ inline const_iterator begin() const { return const_iterator(m_range); }
+ inline const_iterator end() const { return const_iterator(m_range, true); }
+
+ inline iterator begin() { return iterator(m_range); }
+ inline iterator end() { return iterator(m_range, true); }
+private :
+ Range& m_range;
+};
+
+}
+
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief View on a range, either closing it or leaving it as it is
+\details The closeable_view is used internally by the library to handle all rings,
+ either closed or open, the same way. The default method is closed, all
+ algorithms process rings as if they are closed. Therefore, if they are opened,
+ a view is created which closes them.
+ The closeable_view might be used by library users, but its main purpose is
+ internally.
+\tparam Range Original range
+\tparam Close Specifies if it the range is closed, if so, nothing will happen.
+ If it is open, it will iterate the first point after the last point.
+\ingroup views
+*/
+template <typename Range, closure_selector Close>
+struct closeable_view {};
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+template <typename Range>
+struct closeable_view<Range, closed>
+{
+ typedef identity_view<Range> type;
+};
+
+
+template <typename Range>
+struct closeable_view<Range, open>
+{
+ typedef detail::closing_view<Range> type;
+};
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_CLOSEABLE_VIEW_HPP
diff --git a/src/boost/geometry/views/detail/points_view.hpp b/src/boost/geometry/views/detail/points_view.hpp
new file mode 100644
index 0000000..91fbc41
--- /dev/null
+++ b/src/boost/geometry/views/detail/points_view.hpp
@@ -0,0 +1,141 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_DETAIL_POINTS_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_DETAIL_POINTS_VIEW_HPP
+
+
+#include <boost/range.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <boost/geometry/core/exception.hpp>
+
+namespace boost { namespace geometry
+{
+
+namespace detail
+{
+
+// Adapts pointer, on points, to a Boost.Range
+template <typename Point, int MaxSize>
+class points_view
+{
+ // Iterates over a series of points (indicated by pointer
+ // to have it lightweight). Probably there is already an
+ // equivalent of this within Boost. If so, TODO: use that one.
+ // This used to be "box_iterator" and "segment_iterator".
+ struct points_iterator
+ : public boost::iterator_facade
+ <
+ points_iterator,
+ Point const,
+ boost::random_access_traversal_tag
+ >
+ {
+ // Constructor: Begin iterator
+ inline points_iterator(Point const* p)
+ : m_points(p)
+ , m_index(0)
+ {}
+
+ // Constructor: End iterator
+ inline points_iterator(Point const* p, bool)
+ : m_points(p)
+ , m_index(MaxSize)
+ {}
+
+ // Constructor: default (for Range Concept checking).
+ inline points_iterator()
+ : m_points(NULL)
+ , m_index(MaxSize)
+ {}
+
+ typedef std::ptrdiff_t difference_type;
+
+ private:
+ friend class boost::iterator_core_access;
+
+ inline Point const& dereference() const
+ {
+ if (m_index >= 0 && m_index < MaxSize)
+ {
+ return m_points[m_index];
+ }
+
+ // If it index larger (or smaller) return first point
+ // (assuming initialized)
+ return m_points[0];
+ }
+
+ inline bool equal(points_iterator const& other) const
+ {
+ return other.m_index == this->m_index;
+ }
+
+ inline void increment()
+ {
+ m_index++;
+ }
+
+ inline void decrement()
+ {
+ m_index--;
+ }
+
+ inline difference_type distance_to(points_iterator const& other) const
+ {
+ return other.m_index - this->m_index;
+ }
+
+ inline void advance(difference_type n)
+ {
+ m_index += n;
+ }
+
+ Point const* m_points;
+ int m_index;
+ };
+
+public :
+
+ typedef points_iterator const_iterator;
+ typedef points_iterator iterator; // must be defined
+
+ const_iterator begin() const { return const_iterator(m_points); }
+ const_iterator end() const { return const_iterator(m_points, true); }
+
+ // It may NOT be used non-const, so commented:
+ //iterator begin() { return m_begin; }
+ //iterator end() { return m_end; }
+
+protected :
+
+ template <typename CopyPolicy>
+ explicit points_view(CopyPolicy const& copy)
+ {
+ copy.apply(m_points);
+ }
+
+private :
+ // Copy points here - box might define them otherwise
+ Point m_points[MaxSize];
+};
+
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_DETAIL_POINTS_VIEW_HPP
diff --git a/src/boost/geometry/views/detail/range_type.hpp b/src/boost/geometry/views/detail/range_type.hpp
new file mode 100644
index 0000000..a40670c
--- /dev/null
+++ b/src/boost/geometry/views/detail/range_type.hpp
@@ -0,0 +1,106 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_DETAIL_RANGE_TYPE_HPP
+#define BOOST_GEOMETRY_VIEWS_DETAIL_RANGE_TYPE_HPP
+
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/views/box_view.hpp>
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry>
+struct range_type
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry>)
+ );
+};
+
+
+template <typename Geometry>
+struct range_type<ring_tag, Geometry>
+{
+ typedef Geometry type;
+};
+
+template <typename Geometry>
+struct range_type<linestring_tag, Geometry>
+{
+ typedef Geometry type;
+};
+
+
+template <typename Geometry>
+struct range_type<polygon_tag, Geometry>
+{
+ typedef typename ring_type<Geometry>::type type;
+};
+
+template <typename Geometry>
+struct range_type<box_tag, Geometry>
+{
+ typedef box_view<Geometry> type;
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+// Will probably be replaced by the more generic "view_as", therefore in detail
+namespace detail
+{
+
+
+/*!
+\brief Meta-function defining a type which is a boost-range.
+\details
+- For linestrings and rings, it defines the type itself.
+- For polygons it defines the ring type.
+- For multi-points, it defines the type itself
+- For multi-polygons and multi-linestrings, it defines the single-version
+ (so in the end the linestring and ring-type-of-multi-polygon)
+\ingroup iterators
+*/
+template <typename Geometry>
+struct range_type
+{
+ typedef typename dispatch::range_type
+ <
+ typename tag<Geometry>::type,
+ Geometry
+ >::type type;
+};
+
+}
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_DETAIL_RANGE_TYPE_HPP
diff --git a/src/boost/geometry/views/identity_view.hpp b/src/boost/geometry/views/identity_view.hpp
new file mode 100644
index 0000000..5ce6e8e
--- /dev/null
+++ b/src/boost/geometry/views/identity_view.hpp
@@ -0,0 +1,53 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_IDENTITY_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_IDENTITY_VIEW_HPP
+
+
+#include <boost/range.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief View on a range, not modifying anything
+\tparam Range original range
+\ingroup views
+*/
+template <typename Range>
+struct identity_view
+{
+ typedef typename boost::range_iterator<Range const>::type const_iterator;
+ typedef typename boost::range_iterator<Range>::type iterator;
+
+ explicit inline identity_view(Range& r)
+ : m_range(r)
+ {}
+
+ inline const_iterator begin() const { return boost::begin(m_range); }
+ inline const_iterator end() const { return boost::end(m_range); }
+
+ inline iterator begin() { return boost::begin(m_range); }
+ inline iterator end() { return boost::end(m_range); }
+private :
+ Range& m_range;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_IDENTITY_VIEW_HPP
diff --git a/src/boost/geometry/views/reversible_view.hpp b/src/boost/geometry/views/reversible_view.hpp
new file mode 100644
index 0000000..6d6dc0d
--- /dev/null
+++ b/src/boost/geometry/views/reversible_view.hpp
@@ -0,0 +1,74 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_REVERSIBLE_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_REVERSIBLE_VIEW_HPP
+
+
+#include <boost/version.hpp>
+#include <boost/range.hpp>
+#include <boost/range/adaptor/reversed.hpp>
+
+#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/views/identity_view.hpp>
+
+namespace boost { namespace geometry
+{
+
+/*!
+\brief Flag for iterating a reversible_view in forward or reverse direction
+\ingroup views
+*/
+enum iterate_direction { iterate_forward, iterate_reverse };
+
+/*!
+\brief View on a range, reversing direction if necessary
+\tparam Range original range
+\tparam Direction direction of iteration
+\ingroup views
+*/
+template <typename Range, iterate_direction Direction>
+struct reversible_view {};
+
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+template <typename Range>
+struct reversible_view<Range, iterate_forward>
+{
+ typedef identity_view<Range> type;
+};
+
+
+template <typename Range>
+struct reversible_view<Range, iterate_reverse>
+{
+//#if BOOST_VERSION > 104500
+ typedef boost::reversed_range<Range> type;
+/*#else
+ // For older versions of Boost
+ typedef boost::range_detail::reverse_range<Range> type;
+#endif
+*/};
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_REVERSIBLE_VIEW_HPP
diff --git a/src/boost/geometry/views/segment_view.hpp b/src/boost/geometry/views/segment_view.hpp
new file mode 100644
index 0000000..50ff617
--- /dev/null
+++ b/src/boost/geometry/views/segment_view.hpp
@@ -0,0 +1,100 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_VIEWS_SEGMENT_VIEW_HPP
+#define BOOST_GEOMETRY_VIEWS_SEGMENT_VIEW_HPP
+
+
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/views/detail/points_view.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief Makes a segment behave like a linestring or a range
+\details Adapts a segment to the Boost.Range concept, enabling the user to
+ iterate the two segment points. The segment_view is registered as a LineString Concept
+\tparam Segment \tparam_geometry{Segment}
+\ingroup views
+
+\qbk{before.synopsis,
+[heading Model of]
+[link geometry.reference.concepts.concept_linestring LineString Concept]
+}
+
+\qbk{[include reference/views/segment_view.qbk]}
+
+*/
+template <typename Segment>
+struct segment_view
+ : public detail::points_view
+ <
+ typename geometry::point_type<Segment>::type,
+ 2
+ >
+{
+ typedef typename geometry::point_type<Segment>::type point_type;
+
+ /// Constructor accepting the segment to adapt
+ explicit segment_view(Segment const& segment)
+ : detail::points_view<point_type, 2>(copy_policy(segment))
+ {}
+
+private :
+
+ class copy_policy
+ {
+ public :
+ inline copy_policy(Segment const& segment)
+ : m_segment(segment)
+ {}
+
+ inline void apply(point_type* points) const
+ {
+ geometry::detail::assign_point_from_index<0>(m_segment, points[0]);
+ geometry::detail::assign_point_from_index<1>(m_segment, points[1]);
+ }
+ private :
+ Segment const& m_segment;
+ };
+
+};
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+// All segment ranges can be handled as linestrings
+namespace traits
+{
+
+template<typename Segment>
+struct tag<segment_view<Segment> >
+{
+ typedef linestring_tag type;
+};
+
+}
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_VIEWS_SEGMENT_VIEW_HPP
diff --git a/src/boost/range/adaptor/adjacent_filtered.hpp b/src/boost/range/adaptor/adjacent_filtered.hpp
new file mode 100644
index 0000000..f717cb3
--- /dev/null
+++ b/src/boost/range/adaptor/adjacent_filtered.hpp
@@ -0,0 +1,238 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
+#define BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
+
+#include <boost/config.hpp>
+#ifdef BOOST_MSVC
+#pragma warning( push )
+#pragma warning( disable : 4355 )
+#endif
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/next_prior.hpp>
+
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class Iter, class Pred, bool default_pass >
+ class skip_iterator
+ : public boost::iterator_adaptor<
+ skip_iterator<Iter,Pred,default_pass>,
+ Iter,
+ BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
+ boost::forward_traversal_tag,
+ BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
+ BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
+ >
+ , private Pred
+ {
+ private:
+ typedef boost::iterator_adaptor<
+ skip_iterator<Iter,Pred,default_pass>,
+ Iter,
+ BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
+ boost::forward_traversal_tag,
+ BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
+ BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
+ > base_t;
+
+ public:
+ typedef Pred pred_t;
+ typedef Iter iter_t;
+
+ skip_iterator() : m_last() {}
+
+ skip_iterator(iter_t it, iter_t last, const Pred& pred)
+ : base_t(it)
+ , pred_t(pred)
+ , m_last(last)
+ {
+ move_to_next_valid();
+ }
+
+ template<class OtherIter>
+ skip_iterator( const skip_iterator<OtherIter, pred_t, default_pass>& other )
+ : base_t(other.base())
+ , pred_t(other)
+ , m_last(other.m_last) {}
+
+ void move_to_next_valid()
+ {
+ iter_t& it = this->base_reference();
+ pred_t& bi_pred = *this;
+ if (it != m_last)
+ {
+ if (default_pass)
+ {
+ iter_t nxt = ::boost::next(it);
+ while (nxt != m_last && !bi_pred(*it, *nxt))
+ {
+ ++it;
+ ++nxt;
+ }
+ }
+ else
+ {
+ iter_t nxt = ::boost::next(it);
+ for(; nxt != m_last; ++it, ++nxt)
+ {
+ if (bi_pred(*it, *nxt))
+ {
+ break;
+ }
+ }
+ if (nxt == m_last)
+ {
+ it = m_last;
+ }
+ }
+ }
+ }
+
+ void increment()
+ {
+ iter_t& it = this->base_reference();
+ BOOST_ASSERT( it != m_last );
+ ++it;
+ move_to_next_valid();
+ }
+
+ iter_t m_last;
+ };
+
+ template< class P, class R, bool default_pass >
+ struct adjacent_filtered_range
+ : iterator_range< skip_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
+ P,
+ default_pass
+ >
+ >
+ {
+ private:
+ typedef skip_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
+ P,
+ default_pass
+ >
+ skip_iter;
+
+ typedef iterator_range<skip_iter>
+ base_range;
+
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<R>::type raw_iterator;
+
+ public:
+ adjacent_filtered_range( const P& p, R& r )
+ : base_range(skip_iter(boost::begin(r), boost::end(r), p),
+ skip_iter(boost::end(r), boost::end(r), p))
+ {
+ }
+ };
+
+ template< class T >
+ struct adjacent_holder : holder<T>
+ {
+ adjacent_holder( T r ) : holder<T>(r)
+ { }
+ };
+
+ template< class T >
+ struct adjacent_excl_holder : holder<T>
+ {
+ adjacent_excl_holder( T r ) : holder<T>(r)
+ { }
+ };
+
+ template< class ForwardRng, class BinPredicate >
+ inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
+ operator|( ForwardRng& r,
+ const adjacent_holder<BinPredicate>& f )
+ {
+ return adjacent_filtered_range<BinPredicate, ForwardRng, true>( f.val, r );
+ }
+
+ template< class ForwardRng, class BinPredicate >
+ inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
+ operator|( const ForwardRng& r,
+ const adjacent_holder<BinPredicate>& f )
+ {
+ return adjacent_filtered_range<BinPredicate,
+ const ForwardRng, true>( f.val, r );
+ }
+
+ template< class ForwardRng, class BinPredicate >
+ inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
+ operator|( ForwardRng& r,
+ const adjacent_excl_holder<BinPredicate>& f )
+ {
+ return adjacent_filtered_range<BinPredicate, ForwardRng, false>( f.val, r );
+ }
+
+ template< class ForwardRng, class BinPredicate >
+ inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
+ operator|( const ForwardRng& r,
+ const adjacent_excl_holder<BinPredicate>& f )
+ {
+ return adjacent_filtered_range<BinPredicate,
+ const ForwardRng, false>( f.val, r );
+ }
+
+ } // 'range_detail'
+
+ // Bring adjacent_filter_range into the boost namespace so that users of
+ // this library may specify the return type of the '|' operator and
+ // adjacent_filter()
+ using range_detail::adjacent_filtered_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::forwarder<range_detail::adjacent_holder>
+ adjacent_filtered =
+ range_detail::forwarder<range_detail::adjacent_holder>();
+
+ const range_detail::forwarder<range_detail::adjacent_excl_holder>
+ adjacent_filtered_excl =
+ range_detail::forwarder<range_detail::adjacent_excl_holder>();
+ }
+
+ template<class ForwardRng, class BinPredicate>
+ inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
+ adjacent_filter(ForwardRng& rng, BinPredicate filter_pred)
+ {
+ return adjacent_filtered_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
+ }
+
+ template<class ForwardRng, class BinPredicate>
+ inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
+ adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred)
+ {
+ return adjacent_filtered_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
+ }
+
+ } // 'adaptors'
+
+}
+
+#ifdef BOOST_MSVC
+#pragma warning( pop )
+#endif
+
+#endif
diff --git a/src/boost/range/adaptor/argument_fwd.hpp b/src/boost/range/adaptor/argument_fwd.hpp
new file mode 100644
index 0000000..fbfd40c
--- /dev/null
+++ b/src/boost/range/adaptor/argument_fwd.hpp
@@ -0,0 +1,80 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP
+#define BOOST_RANGE_ADAPTOR_ARGUMENT_FWD_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4512) // assignment operator could not be generated
+#endif
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class T >
+ struct holder
+ {
+ T val;
+ holder( T t ) : val(t)
+ { }
+ };
+
+ template< class T >
+ struct holder2
+ {
+ T val1, val2;
+ holder2( T t, T u ) : val1(t), val2(u)
+ { }
+ };
+
+ template< template<class> class Holder >
+ struct forwarder
+ {
+ template< class T >
+ Holder<T> operator()( T t ) const
+ {
+ return Holder<T>(t);
+ }
+ };
+
+ template< template<class> class Holder >
+ struct forwarder2
+ {
+ template< class T >
+ Holder<T> operator()( T t, T u ) const
+ {
+ return Holder<T>(t,u);
+ }
+ };
+
+ template< template<class,class> class Holder >
+ struct forwarder2TU
+ {
+ template< class T, class U >
+ Holder<T, U> operator()( T t, U u ) const
+ {
+ return Holder<T, U>(t, u);
+ }
+ };
+
+
+ }
+
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/src/boost/range/adaptor/copied.hpp b/src/boost/range/adaptor/copied.hpp
new file mode 100644
index 0000000..f4cf2d1
--- /dev/null
+++ b/src/boost/range/adaptor/copied.hpp
@@ -0,0 +1,58 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_COPIED_HPP
+#define BOOST_RANGE_ADAPTOR_COPIED_HPP
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/adaptor/sliced.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+ namespace adaptors
+ {
+ struct copied
+ {
+ copied(std::size_t t_, std::size_t u_)
+ : t(t_), u(u_) {}
+
+ std::size_t t;
+ std::size_t u;
+ };
+
+ template< class CopyableRandomAccessRng >
+ inline CopyableRandomAccessRng
+ operator|( const CopyableRandomAccessRng& r, const copied& f )
+ {
+ iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<const
+ CopyableRandomAccessRng>::type >
+ temp( adaptors::slice( r, f.t, f.u ) );
+ return CopyableRandomAccessRng( temp.begin(), temp.end() );
+ }
+
+ template<class CopyableRandomAccessRange>
+ inline CopyableRandomAccessRange
+ copy(const CopyableRandomAccessRange& rng, std::size_t t, std::size_t u)
+ {
+ iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<const
+ CopyableRandomAccessRange>::type> temp(
+ adaptors::slice(rng, t, u));
+
+ return CopyableRandomAccessRange( temp.begin(), temp.end() );
+ }
+ } // 'adaptors'
+
+}
+
+#endif
diff --git a/src/boost/range/adaptor/define_adaptor.hpp b/src/boost/range/adaptor/define_adaptor.hpp
new file mode 100644
index 0000000..b228df3
--- /dev/null
+++ b/src/boost/range/adaptor/define_adaptor.hpp
@@ -0,0 +1,109 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
+#define BOOST_RANGE_DEFINE_ADAPTOR_HPP_INCLUDED
+
+#include <boost/tuple/tuple.hpp>
+
+#define BOOST_DEFINE_RANGE_ADAPTOR( adaptor_name, range_adaptor ) \
+ struct adaptor_name##_forwarder {}; \
+ \
+ template<typename Range> range_adaptor <Range> \
+ operator|(Range& rng, adaptor_name##_forwarder) \
+ { \
+ return range_adaptor <Range>( rng ); \
+ } \
+ \
+ template<typename Range> range_adaptor <const Range> \
+ operator|(const Range& rng, adaptor_name##_forwarder) \
+ { \
+ return range_adaptor <const Range>( rng ); \
+ } \
+ \
+ static adaptor_name##_forwarder adaptor_name = adaptor_name##_forwarder(); \
+ \
+ template<typename Range> \
+ range_adaptor <Range> \
+ make_##adaptor_name(Range& rng) \
+ { \
+ return range_adaptor <Range>(rng); \
+ } \
+ \
+ template<typename Range> \
+ range_adaptor <const Range> \
+ make_##adaptor_name(const Range& rng) \
+ { \
+ return range_adaptor <const Range>(rng); \
+ }
+
+#define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, arg1_type ) \
+ struct adaptor_name \
+ { \
+ explicit adaptor_name (arg1_type arg1_) \
+ : arg1(arg1_) {} \
+ arg1_type arg1; \
+ }; \
+ \
+ template<typename Range> range_adaptor <Range> \
+ operator|(Range& rng, adaptor_name args) \
+ { \
+ return range_adaptor <Range>(rng, args.arg1); \
+ } \
+ \
+ template<typename Range> range_adaptor <const Range> \
+ operator|(const Range& rng, adaptor_name args) \
+ { \
+ return range_adaptor <const Range>(rng, args.arg1); \
+ } \
+ \
+ template<typename Range> \
+ range_adaptor <Range> \
+ make_##adaptor_name(Range& rng, arg1_type arg1) \
+ { \
+ return range_adaptor <Range>(rng, arg1); \
+ } \
+ \
+ template<typename Range> \
+ range_adaptor <const Range> \
+ make_##adaptor_name(const Range& rng, arg1_type arg1) \
+ { \
+ return range_adaptor <const Range>(rng, arg1); \
+ }
+
+#define BOOST_RANGE_ADAPTOR_2( adaptor_name, range_adaptor, arg1_type, arg2_type ) \
+ struct adaptor_name \
+ { \
+ explicit adaptor_name (arg1_type arg1_, arg2_type arg2_) \
+ : arg1(arg1_), arg2(arg2_) {} \
+ arg1_type arg1; \
+ arg2_type arg2; \
+ }; \
+ \
+ template<typename Range> range_adaptor <Range> \
+ operator|(Range& rng, adaptor_name args) \
+ { \
+ return range_adaptor <Range>(rng, args.arg1, args.arg2); \
+ } \
+ template<typename Range> \
+ range_adaptor <Range> \
+ make_##adaptor_name(Range& rng, arg1_type arg1, arg2_type arg2) \
+ { \
+ return range_adaptor <Range>(rng, arg1, arg2); \
+ } \
+ template<typename Range> \
+ range_adaptor <const Range> \
+ make_##adaptor_name(const Range& rng, arg1_type arg1, arg2_type arg2) \
+ { \
+ return range_adaptor <const Range>(rng, arg1, arg2); \
+ }
+
+
+#endif // include guard
diff --git a/src/boost/range/adaptor/filtered.hpp b/src/boost/range/adaptor/filtered.hpp
new file mode 100644
index 0000000..d9315bd
--- /dev/null
+++ b/src/boost/range/adaptor/filtered.hpp
@@ -0,0 +1,101 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_FILTERED_HPP
+#define BOOST_RANGE_ADAPTOR_FILTERED_HPP
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/filter_iterator.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class P, class R >
+ struct filtered_range :
+ boost::iterator_range<
+ boost::filter_iterator< P,
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ >
+ {
+ private:
+ typedef boost::iterator_range<
+ boost::filter_iterator< P,
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ > base;
+ public:
+ filtered_range( P p, R& r )
+ : base( make_filter_iterator( p, boost::begin(r), boost::end(r) ),
+ make_filter_iterator( p, boost::end(r), boost::end(r) ) )
+ { }
+ };
+
+ template< class T >
+ struct filter_holder : holder<T>
+ {
+ filter_holder( T r ) : holder<T>(r)
+ { }
+ };
+
+ template< class InputRng, class Predicate >
+ inline filtered_range<Predicate, InputRng>
+ operator|( InputRng& r,
+ const filter_holder<Predicate>& f )
+ {
+ return filtered_range<Predicate, InputRng>( f.val, r );
+ }
+
+ template< class InputRng, class Predicate >
+ inline filtered_range<Predicate, const InputRng>
+ operator|( const InputRng& r,
+ const filter_holder<Predicate>& f )
+ {
+ return filtered_range<Predicate, const InputRng>( f.val, r );
+ }
+
+ } // 'range_detail'
+
+ // Unusual use of 'using' is intended to bring filter_range into the boost namespace
+ // while leaving the mechanics of the '|' operator in range_detail and maintain
+ // argument dependent lookup.
+ // filter_range logically needs to be in the boost namespace to allow user of
+ // the library to define the return type for filter()
+ using range_detail::filtered_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::forwarder<range_detail::filter_holder>
+ filtered =
+ range_detail::forwarder<range_detail::filter_holder>();
+ }
+
+ template<class InputRange, class Predicate>
+ inline filtered_range<Predicate, InputRange>
+ filter(InputRange& rng, Predicate filter_pred)
+ {
+ return range_detail::filtered_range<Predicate, InputRange>( filter_pred, rng );
+ }
+
+ template<class InputRange, class Predicate>
+ inline filtered_range<Predicate, const InputRange>
+ filter(const InputRange& rng, Predicate filter_pred)
+ {
+ return range_detail::filtered_range<Predicate, const InputRange>( filter_pred, rng );
+ }
+ } // 'adaptors'
+
+}
+
+#endif
diff --git a/src/boost/range/adaptor/indexed.hpp b/src/boost/range/adaptor/indexed.hpp
new file mode 100644
index 0000000..5a523ce
--- /dev/null
+++ b/src/boost/range/adaptor/indexed.hpp
@@ -0,0 +1,156 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP
+#define BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP
+
+#include <boost/config.hpp>
+#ifdef BOOST_MSVC
+#pragma warning( push )
+#pragma warning( disable : 4355 )
+#endif
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+
+
+
+namespace boost
+{
+ namespace adaptors
+ {
+ // This structure exists to carry the parameters from the '|' operator
+ // to the index adapter. The expression rng | indexed(1) instantiates
+ // this structure and passes it as the right-hand operand to the
+ // '|' operator.
+ struct indexed
+ {
+ explicit indexed(std::size_t x) : val(x) {}
+ std::size_t val;
+ };
+ }
+
+ namespace range_detail
+ {
+ template< class Iter >
+ class indexed_iterator
+ : public boost::iterator_adaptor< indexed_iterator<Iter>, Iter >
+ {
+ private:
+ typedef boost::iterator_adaptor< indexed_iterator<Iter>, Iter >
+ base;
+
+ typedef BOOST_DEDUCED_TYPENAME base::difference_type index_type;
+
+ index_type m_index;
+
+ public:
+ explicit indexed_iterator( Iter i, index_type index )
+ : base(i), m_index(index)
+ {
+ BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" );
+ }
+
+ index_type index() const
+ {
+ return m_index;
+ }
+
+ private:
+ friend class boost::iterator_core_access;
+
+ void increment()
+ {
+ ++m_index;
+ ++(this->base_reference());
+ }
+
+
+ void decrement()
+ {
+ BOOST_ASSERT( m_index > 0 && "Indexed Iterator out of bounds" );
+ --m_index;
+ --(this->base_reference());
+ }
+
+ void advance( index_type n )
+ {
+ m_index += n;
+ BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" );
+ this->base_reference() += n;
+ }
+ };
+
+ template< class Rng >
+ struct indexed_range :
+ iterator_range< indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> >
+ {
+ private:
+ typedef indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type>
+ iter_type;
+ typedef iterator_range<iter_type>
+ base;
+ public:
+ template< class Index >
+ indexed_range( Index i, Rng& r )
+ : base( iter_type(boost::begin(r), i), iter_type(boost::end(r),i) )
+ { }
+ };
+
+ } // 'range_detail'
+
+ // Make this available to users of this library. It will sometimes be
+ // required since it is the return type of operator '|' and
+ // index().
+ using range_detail::indexed_range;
+
+ namespace adaptors
+ {
+ template< class SinglePassRange >
+ inline indexed_range<SinglePassRange>
+ operator|( SinglePassRange& r,
+ const indexed& f )
+ {
+ return indexed_range<SinglePassRange>( f.val, r );
+ }
+
+ template< class SinglePassRange >
+ inline indexed_range<const SinglePassRange>
+ operator|( const SinglePassRange& r,
+ const indexed& f )
+ {
+ return indexed_range<const SinglePassRange>( f.val, r );
+ }
+
+ template<class SinglePassRange, class Index>
+ inline indexed_range<SinglePassRange>
+ index(SinglePassRange& rng, Index index_value)
+ {
+ return indexed_range<SinglePassRange>(index_value, rng);
+ }
+
+ template<class SinglePassRange, class Index>
+ inline indexed_range<const SinglePassRange>
+ index(const SinglePassRange& rng, Index index_value)
+ {
+ return indexed_range<const SinglePassRange>(index_value, rng);
+ }
+ } // 'adaptors'
+
+}
+
+#ifdef BOOST_MSVC
+#pragma warning( pop )
+#endif
+
+#endif
diff --git a/src/boost/range/adaptor/indirected.hpp b/src/boost/range/adaptor/indirected.hpp
new file mode 100644
index 0000000..d7edc18
--- /dev/null
+++ b/src/boost/range/adaptor/indirected.hpp
@@ -0,0 +1,88 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_INDIRECTED_HPP
+#define BOOST_RANGE_ADAPTOR_INDIRECTED_HPP
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class R >
+ struct indirected_range :
+ public boost::iterator_range<
+ boost::indirect_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ >
+ {
+ private:
+ typedef boost::iterator_range<
+ boost::indirect_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ >
+ base;
+
+ public:
+ explicit indirected_range( R& r )
+ : base( r )
+ { }
+ };
+
+ struct indirect_forwarder {};
+
+ template< class InputRng >
+ inline indirected_range<InputRng>
+ operator|( InputRng& r, indirect_forwarder )
+ {
+ return indirected_range<InputRng>( r );
+ }
+
+ template< class InputRng >
+ inline indirected_range<const InputRng>
+ operator|( const InputRng& r, indirect_forwarder )
+ {
+ return indirected_range<const InputRng>( r );
+ }
+
+ } // 'range_detail'
+
+ using range_detail::indirected_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::indirect_forwarder indirected =
+ range_detail::indirect_forwarder();
+ }
+
+ template<class InputRange>
+ inline indirected_range<InputRange>
+ indirect(InputRange& rng)
+ {
+ return indirected_range<InputRange>(rng);
+ }
+
+ template<class InputRange>
+ inline indirected_range<const InputRange>
+ indirect(const InputRange& rng)
+ {
+ return indirected_range<const InputRange>(rng);
+ }
+ } // 'adaptors'
+
+}
+
+#endif
diff --git a/src/boost/range/adaptor/map.hpp b/src/boost/range/adaptor/map.hpp
new file mode 100644
index 0000000..ff8b97e
--- /dev/null
+++ b/src/boost/range/adaptor/map.hpp
@@ -0,0 +1,187 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_MAP_HPP
+#define BOOST_RANGE_ADAPTOR_MAP_HPP
+
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/reference.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ struct map_keys_forwarder {};
+ struct map_values_forwarder {};
+
+ template< class Map >
+ struct select_first
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
+ typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::first_type& result_type;
+
+ result_type operator()( argument_type r ) const
+ {
+ return r.first;
+ }
+ };
+
+ template< class Map >
+ struct select_second_mutable
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_reference<Map>::type argument_type;
+ typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type::second_type& result_type;
+
+ result_type operator()( argument_type r ) const
+ {
+ return r.second;
+ }
+ };
+
+ template< class Map >
+ struct select_second_const
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
+ typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::second_type& result_type;
+
+ result_type operator()( argument_type r ) const
+ {
+ return r.second;
+ }
+ };
+
+ template<class StdPairRng>
+ class select_first_range
+ : public transformed_range<
+ select_first<StdPairRng>,
+ const StdPairRng>
+ {
+ typedef transformed_range<select_first<StdPairRng>, const StdPairRng> base;
+ public:
+ typedef select_first<StdPairRng> transform_fn_type;
+ typedef const StdPairRng source_range_type;
+
+ select_first_range(transform_fn_type fn, source_range_type& rng)
+ : base(fn, rng)
+ {
+ }
+
+ select_first_range(const base& other) : base(other) {}
+ };
+
+ template<class StdPairRng>
+ class select_second_mutable_range
+ : public transformed_range<
+ select_second_mutable<StdPairRng>,
+ StdPairRng>
+ {
+ typedef transformed_range<select_second_mutable<StdPairRng>, StdPairRng> base;
+ public:
+ typedef select_second_mutable<StdPairRng> transform_fn_type;
+ typedef StdPairRng source_range_type;
+
+ select_second_mutable_range(transform_fn_type fn, source_range_type& rng)
+ : base(fn, rng)
+ {
+ }
+
+ select_second_mutable_range(const base& other) : base(other) {}
+ };
+
+ template<class StdPairRng>
+ class select_second_const_range
+ : public transformed_range<
+ select_second_const<StdPairRng>,
+ const StdPairRng>
+ {
+ typedef transformed_range<select_second_const<StdPairRng>, const StdPairRng> base;
+ public:
+ typedef select_second_const<StdPairRng> transform_fn_type;
+ typedef const StdPairRng source_range_type;
+
+ select_second_const_range(transform_fn_type fn, source_range_type& rng)
+ : base(fn, rng)
+ {
+ }
+
+ select_second_const_range(const base& other) : base(other) {}
+ };
+
+ template< class StdPairRng >
+ inline select_first_range<StdPairRng>
+ operator|( const StdPairRng& r, map_keys_forwarder )
+ {
+ return operator|( r,
+ boost::adaptors::transformed( select_first<StdPairRng>() ) );
+ }
+
+ template< class StdPairRng >
+ inline select_second_mutable_range<StdPairRng>
+ operator|( StdPairRng& r, map_values_forwarder )
+ {
+ return operator|( r,
+ boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) );
+ }
+
+ template< class StdPairRng >
+ inline select_second_const_range<StdPairRng>
+ operator|( const StdPairRng& r, map_values_forwarder )
+ {
+ return operator|( r,
+ boost::adaptors::transformed( select_second_const<StdPairRng>() ) );
+ }
+
+ } // 'range_detail'
+
+ using range_detail::select_first_range;
+ using range_detail::select_second_mutable_range;
+ using range_detail::select_second_const_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::map_keys_forwarder map_keys =
+ range_detail::map_keys_forwarder();
+
+ const range_detail::map_values_forwarder map_values =
+ range_detail::map_values_forwarder();
+ }
+
+ template<class StdPairRange>
+ inline select_first_range<StdPairRange>
+ keys(const StdPairRange& rng)
+ {
+ return select_first_range<StdPairRange>(
+ range_detail::select_first<StdPairRange>(), rng );
+ }
+
+ template<class StdPairRange>
+ inline select_second_const_range<StdPairRange>
+ values(const StdPairRange& rng)
+ {
+ return select_second_const_range<StdPairRange>(
+ range_detail::select_second_const<StdPairRange>(), rng );
+ }
+
+ template<class StdPairRange>
+ inline select_second_mutable_range<StdPairRange>
+ values(StdPairRange& rng)
+ {
+ return select_second_mutable_range<StdPairRange>(
+ range_detail::select_second_mutable<StdPairRange>(), rng );
+ }
+ } // 'adaptors'
+
+}
+
+#endif
diff --git a/src/boost/range/adaptor/replaced.hpp b/src/boost/range/adaptor/replaced.hpp
new file mode 100644
index 0000000..deeb8da
--- /dev/null
+++ b/src/boost/range/adaptor/replaced.hpp
@@ -0,0 +1,134 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_REPLACED_IMPL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class Value >
+ class replace_value
+ {
+ public:
+ typedef const Value& result_type;
+ typedef const Value& first_argument_type;
+
+ replace_value(const Value& from, const Value& to)
+ : m_from(from), m_to(to)
+ {
+ }
+
+ const Value& operator()(const Value& x) const
+ {
+ return (x == m_from) ? m_to : x;
+ }
+
+ private:
+ Value m_from;
+ Value m_to;
+ };
+
+ template< class R >
+ class replaced_range :
+ public boost::iterator_range<
+ boost::transform_iterator<
+ replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
+ {
+ private:
+ typedef replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
+
+ typedef boost::iterator_range<
+ boost::transform_iterator<
+ replace_value< BOOST_DEDUCED_TYPENAME range_value<R>::type >,
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
+
+ public:
+ typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
+
+ replaced_range( R& r, value_type from, value_type to )
+ : base_t( make_transform_iterator( boost::begin(r), Fn(from, to) ),
+ make_transform_iterator( boost::end(r), Fn(from, to) ) )
+ { }
+ };
+
+ template< class T >
+ class replace_holder : public holder2<T>
+ {
+ public:
+ replace_holder( const T& from, const T& to )
+ : holder2<T>(from, to)
+ { }
+ private:
+ // not assignable
+ void operator=(const replace_holder&);
+ };
+
+ template< class InputRng >
+ inline replaced_range<InputRng>
+ operator|( InputRng& r,
+ const replace_holder<BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
+ {
+ return replaced_range<InputRng>(r, f.val1, f.val2);
+ }
+
+ template< class InputRng >
+ inline replaced_range<const InputRng>
+ operator|( const InputRng& r,
+ const replace_holder<BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
+ {
+ return replaced_range<const InputRng>(r, f.val1, f.val2);
+ }
+ } // 'range_detail'
+
+ using range_detail::replaced_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::forwarder2<range_detail::replace_holder>
+ replaced =
+ range_detail::forwarder2<range_detail::replace_holder>();
+ }
+
+ template<class InputRange>
+ inline replaced_range<InputRange>
+ replace(InputRange& rng,
+ BOOST_DEDUCED_TYPENAME range_value<InputRange>::type from,
+ BOOST_DEDUCED_TYPENAME range_value<InputRange>::type to)
+ {
+ return replaced_range<InputRange>(rng, from, to);
+ }
+
+ template<class InputRange>
+ inline replaced_range<const InputRange>
+ replace(const InputRange& rng,
+ BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type from,
+ BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type to)
+ {
+ return replaced_range<const InputRange>(rng, from ,to);
+ }
+
+ } // 'adaptors'
+} // 'boost'
+
+#endif // include guard
diff --git a/src/boost/range/adaptor/replaced_if.hpp b/src/boost/range/adaptor/replaced_if.hpp
new file mode 100644
index 0000000..b514354
--- /dev/null
+++ b/src/boost/range/adaptor/replaced_if.hpp
@@ -0,0 +1,136 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_REPLACED_IF_IMPL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class Pred, class Value >
+ class replace_value_if
+ {
+ public:
+ typedef const Value& result_type;
+ typedef const Value& first_argument_type;
+
+ replace_value_if(const Pred& pred, const Value& to)
+ : m_pred(pred), m_to(to)
+ {
+ }
+
+ const Value& operator()(const Value& x) const
+ {
+ return m_pred(x) ? m_to : x;
+ }
+
+ private:
+ Pred m_pred;
+ Value m_to;
+ };
+
+ template< class Pred, class R >
+ class replaced_if_range :
+ public boost::iterator_range<
+ boost::transform_iterator<
+ replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type > >
+ {
+ private:
+ typedef replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type > Fn;
+
+ typedef boost::iterator_range<
+ boost::transform_iterator<
+ replace_value_if< Pred, BOOST_DEDUCED_TYPENAME range_value<R>::type >,
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type > > base_t;
+
+ public:
+ typedef BOOST_DEDUCED_TYPENAME range_value<R>::type value_type;
+
+ replaced_if_range( R& r, const Pred& pred, value_type to )
+ : base_t( make_transform_iterator( boost::begin(r), Fn(pred, to) ),
+ make_transform_iterator( boost::end(r), Fn(pred, to) ) )
+ { }
+ };
+
+ template< class Pred, class T >
+ class replace_if_holder
+ {
+ public:
+ replace_if_holder( const Pred& pred, const T& to )
+ : m_pred(pred), m_to(to)
+ { }
+
+ const Pred& pred() const { return m_pred; }
+ const T& to() const { return m_to; }
+
+ private:
+ Pred m_pred;
+ T m_to;
+ };
+
+ template< class Pred, class InputRng >
+ inline replaced_if_range<Pred, InputRng>
+ operator|( InputRng& r,
+ const replace_if_holder<Pred, BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
+ {
+ return replaced_if_range<Pred, InputRng>(r, f.pred(), f.to());
+ }
+
+ template< class Pred, class InputRng >
+ inline replaced_if_range<Pred, const InputRng>
+ operator|( const InputRng& r,
+ const replace_if_holder<Pred, BOOST_DEDUCED_TYPENAME range_value<InputRng>::type>& f )
+ {
+ return replaced_if_range<Pred, const InputRng>(r, f.pred(), f.to());
+ }
+ } // 'range_detail'
+
+ using range_detail::replaced_if_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::forwarder2TU<range_detail::replace_if_holder>
+ replaced_if =
+ range_detail::forwarder2TU<range_detail::replace_if_holder>();
+ }
+
+ template<class Pred, class InputRange>
+ inline replaced_if_range<Pred, InputRange>
+ replace_if(InputRange& rng, Pred pred,
+ BOOST_DEDUCED_TYPENAME range_value<InputRange>::type to)
+ {
+ return range_detail::replaced_if_range<Pred, InputRange>(rng, pred, to);
+ }
+
+ template<class Pred, class InputRange>
+ inline replaced_if_range<Pred, const InputRange>
+ replace_if(const InputRange& rng, Pred pred,
+ BOOST_DEDUCED_TYPENAME range_value<const InputRange>::type to)
+ {
+ return range_detail::replaced_if_range<Pred, const InputRange>(rng, pred, to);
+ }
+ } // 'adaptors'
+
+} // 'boost'
+
+#endif // include guard
diff --git a/src/boost/range/adaptor/reversed.hpp b/src/boost/range/adaptor/reversed.hpp
new file mode 100644
index 0000000..c85eda8
--- /dev/null
+++ b/src/boost/range/adaptor/reversed.hpp
@@ -0,0 +1,90 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_REVERSED_HPP
+#define BOOST_RANGE_ADAPTOR_REVERSED_HPP
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class R >
+ struct reversed_range :
+ public boost::iterator_range<
+ boost::reverse_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ >
+ {
+ private:
+ typedef boost::iterator_range<
+ boost::reverse_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ >
+ base;
+
+ public:
+ typedef boost::reverse_iterator<BOOST_DEDUCED_TYPENAME range_iterator<R>::type> iterator;
+
+ explicit reversed_range( R& r )
+ : base( iterator(boost::end(r)), iterator(boost::begin(r)) )
+ { }
+ };
+
+ struct reverse_forwarder {};
+
+ template< class BidirectionalRng >
+ inline reversed_range<BidirectionalRng>
+ operator|( BidirectionalRng& r, reverse_forwarder )
+ {
+ return reversed_range<BidirectionalRng>( r );
+ }
+
+ template< class BidirectionalRng >
+ inline reversed_range<const BidirectionalRng>
+ operator|( const BidirectionalRng& r, reverse_forwarder )
+ {
+ return reversed_range<const BidirectionalRng>( r );
+ }
+
+ } // 'range_detail'
+
+ using range_detail::reversed_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::reverse_forwarder reversed =
+ range_detail::reverse_forwarder();
+ }
+
+ template<class BidirectionalRange>
+ inline reversed_range<BidirectionalRange>
+ reverse(BidirectionalRange& rng)
+ {
+ return reversed_range<BidirectionalRange>(rng);
+ }
+
+ template<class BidirectionalRange>
+ inline reversed_range<const BidirectionalRange>
+ reverse(const BidirectionalRange& rng)
+ {
+ return reversed_range<const BidirectionalRange>(rng);
+ }
+ } // 'adaptors'
+
+} // 'boost'
+
+#endif
diff --git a/src/boost/range/adaptor/sliced.hpp b/src/boost/range/adaptor/sliced.hpp
new file mode 100644
index 0000000..14ad986
--- /dev/null
+++ b/src/boost/range/adaptor/sliced.hpp
@@ -0,0 +1,82 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_SLICED_HPP
+#define BOOST_RANGE_ADAPTOR_SLICED_HPP
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+ namespace adaptors
+ {
+ struct sliced
+ {
+ sliced(std::size_t t_, std::size_t u_)
+ : t(t_), u(u_) {}
+ std::size_t t;
+ std::size_t u;
+ };
+
+ template< class RandomAccessRange >
+ class sliced_range : public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type >
+ {
+ typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type > base_t;
+ public:
+ template<typename Rng, typename T, typename U>
+ sliced_range(Rng& rng, T t, U u)
+ : base_t(boost::make_iterator_range(rng, t, u - boost::size(rng)))
+ {
+ }
+ };
+
+ template< class RandomAccessRange >
+ inline sliced_range<RandomAccessRange>
+ slice( RandomAccessRange& rng, std::size_t t, std::size_t u )
+ {
+ BOOST_ASSERT( t <= u && "error in slice indices" );
+ BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
+ "second slice index out of bounds" );
+
+ return sliced_range<RandomAccessRange>(rng, t, u);
+ }
+
+ template< class RandomAccessRange >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type >
+ slice( const RandomAccessRange& rng, std::size_t t, std::size_t u )
+ {
+ BOOST_ASSERT( t <= u && "error in slice indices" );
+ BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
+ "second slice index out of bounds" );
+
+ return sliced_range<const RandomAccessRange>(rng, t, u);
+ }
+
+ template< class RandomAccessRange >
+ inline sliced_range<RandomAccessRange>
+ operator|( RandomAccessRange& r, const sliced& f )
+ {
+ return sliced_range<RandomAccessRange>( r, f.t, f.u );
+ }
+
+ template< class RandomAccessRange >
+ inline sliced_range<const RandomAccessRange>
+ operator|( const RandomAccessRange& r, const sliced& f )
+ {
+ return sliced_range<const RandomAccessRange>( r, f.t, f.u );
+ }
+
+ } // namespace adaptors
+ using adaptors::sliced_range;
+} // namespace boost
+
+#endif
diff --git a/src/boost/range/adaptor/strided.hpp b/src/boost/range/adaptor/strided.hpp
new file mode 100644
index 0000000..e843f62
--- /dev/null
+++ b/src/boost/range/adaptor/strided.hpp
@@ -0,0 +1,350 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_STRIDED_HPP_INCLUDED
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <iterator>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ // strided_iterator for wrapping a forward traversal iterator
+ template<class BaseIterator, class Category>
+ class strided_iterator
+ : public iterator_adaptor<
+ strided_iterator<BaseIterator, Category>
+ , BaseIterator
+ , use_default
+ , boost::forward_traversal_tag
+ >
+ {
+ friend class ::boost::iterator_core_access;
+
+ typedef iterator_adaptor<
+ strided_iterator<BaseIterator, Category>
+ , BaseIterator
+ , use_default
+ , boost::forward_traversal_tag
+ > super_t;
+
+ public:
+ typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
+ typedef BaseIterator base_iterator;
+
+ strided_iterator()
+ : m_last()
+ , m_stride()
+ {
+ }
+
+ strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride)
+ : super_t(it)
+ , m_last(last)
+ , m_stride(stride)
+ {
+ }
+
+ template<class OtherIterator>
+ strided_iterator(const strided_iterator<OtherIterator, Category>& other,
+ BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0)
+ : super_t(other)
+ , m_last(other.base_end())
+ , m_stride(other.get_stride())
+ {
+ }
+
+ base_iterator base_end() const { return m_last; }
+ difference_type get_stride() const { return m_stride; }
+
+ private:
+ void increment()
+ {
+ base_iterator& it = this->base_reference();
+ for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i)
+ ++it;
+ }
+
+ base_iterator m_last;
+ difference_type m_stride;
+ };
+
+ // strided_iterator for wrapping a bidirectional iterator
+ template<class BaseIterator>
+ class strided_iterator<BaseIterator, bidirectional_traversal_tag>
+ : public iterator_adaptor<
+ strided_iterator<BaseIterator, bidirectional_traversal_tag>
+ , BaseIterator
+ , use_default
+ , bidirectional_traversal_tag
+ >
+ {
+ friend class ::boost::iterator_core_access;
+
+ typedef iterator_adaptor<
+ strided_iterator<BaseIterator, bidirectional_traversal_tag>
+ , BaseIterator
+ , use_default
+ , bidirectional_traversal_tag
+ > super_t;
+ public:
+ typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<BaseIterator>::difference_type difference_type;
+ typedef BaseIterator base_iterator;
+
+ strided_iterator()
+ : m_first()
+ , m_last()
+ , m_stride()
+ {
+ }
+
+ strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride)
+ : super_t(it)
+ , m_first(first)
+ , m_last(last)
+ , m_stride(stride)
+ {
+ }
+
+ template<class OtherIterator>
+ strided_iterator(const strided_iterator<OtherIterator, bidirectional_traversal_tag>& other,
+ BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, base_iterator>::type* = 0)
+ : super_t(other.base())
+ , m_first(other.base_begin())
+ , m_last(other.base_end())
+ , m_stride(other.get_stride())
+ {
+ }
+
+ base_iterator base_begin() const { return m_first; }
+ base_iterator base_end() const { return m_last; }
+ difference_type get_stride() const { return m_stride; }
+
+ private:
+ void increment()
+ {
+ base_iterator& it = this->base_reference();
+ for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i)
+ ++it;
+ }
+
+ void decrement()
+ {
+ base_iterator& it = this->base_reference();
+ for (difference_type i = 0; (it != m_first) && (i < m_stride); ++i)
+ --it;
+ }
+
+ base_iterator m_first;
+ base_iterator m_last;
+ difference_type m_stride;
+ };
+
+ // strided_iterator implementation for wrapping a random access iterator
+ template<class BaseIterator>
+ class strided_iterator<BaseIterator, random_access_traversal_tag>
+ : public iterator_adaptor<
+ strided_iterator<BaseIterator, random_access_traversal_tag>
+ , BaseIterator
+ , use_default
+ , random_access_traversal_tag
+ >
+ {
+ friend class ::boost::iterator_core_access;
+
+ typedef iterator_adaptor<
+ strided_iterator<BaseIterator, random_access_traversal_tag>
+ , BaseIterator
+ , use_default
+ , random_access_traversal_tag
+ > super_t;
+ public:
+ typedef BOOST_DEDUCED_TYPENAME super_t::difference_type difference_type;
+ typedef BaseIterator base_iterator;
+
+ strided_iterator()
+ : m_first()
+ , m_last()
+ , m_index(0)
+ , m_stride()
+ {
+ }
+
+ strided_iterator(BaseIterator first, BaseIterator it, BaseIterator last, difference_type stride)
+ : super_t(it)
+ , m_first(first)
+ , m_last(last)
+ , m_index(stride ? (it - first) / stride : 0)
+ , m_stride(stride)
+ {
+ }
+
+ template<class OtherIterator>
+ strided_iterator(const strided_iterator<OtherIterator, random_access_traversal_tag>& other,
+ BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0)
+ : super_t(other.base())
+ , m_first(other.base_begin())
+ , m_last(other.base_end())
+ , m_index(other.get_index())
+ , m_stride(other.get_stride())
+ {
+ }
+
+ base_iterator base_begin() const { return m_first; }
+ base_iterator base_end() const { return m_last; }
+ difference_type get_stride() const { return m_stride; }
+ difference_type get_index() const { return m_index; }
+
+ private:
+ void increment()
+ {
+ m_index += m_stride;
+ if (m_index < (m_last - m_first))
+ this->base_reference() = m_first + m_index;
+ else
+ this->base_reference() = m_last;
+ }
+
+ void decrement()
+ {
+ m_index -= m_stride;
+ if (m_index >= 0)
+ this->base_reference() = m_first + m_index;
+ else
+ this->base_reference() = m_first;
+ }
+
+ void advance(difference_type offset)
+ {
+ offset *= m_stride;
+ m_index += offset;
+ if (m_index < 0)
+ this->base_reference() = m_first;
+ else if (m_index > (m_last - m_first))
+ this->base_reference() = m_last;
+ else
+ this->base_reference() = m_first + m_index;
+ }
+
+ template<class OtherIterator>
+ difference_type distance_to(const strided_iterator<OtherIterator, random_access_traversal_tag>& other,
+ BOOST_DEDUCED_TYPENAME enable_if_convertible<OtherIterator, BaseIterator>::type* = 0) const
+ {
+ if (other.base() >= this->base())
+ return (other.base() - this->base() + (m_stride - 1)) / m_stride;
+ return (other.base() - this->base() - (m_stride - 1)) / m_stride;
+ }
+
+ bool equal(const strided_iterator& other) const
+ {
+ return this->base() == other.base();
+ }
+
+ private:
+ base_iterator m_first;
+ base_iterator m_last;
+ difference_type m_index;
+ difference_type m_stride;
+ };
+
+ template<class BaseIterator, class Difference> inline
+ strided_iterator<BaseIterator, BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type>
+ make_strided_iterator(BaseIterator first, BaseIterator it,
+ BaseIterator last, Difference stride)
+ {
+ BOOST_ASSERT( stride >= 0 );
+ typedef BOOST_DEDUCED_TYPENAME iterator_traversal<BaseIterator>::type traversal_tag;
+ return strided_iterator<BaseIterator, traversal_tag>(first, it, last, stride);
+ }
+
+ template< class Rng
+ , class Category = BOOST_DEDUCED_TYPENAME iterator_traversal<
+ BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type
+ >::type
+ >
+ class strided_range
+ : public iterator_range<
+ range_detail::strided_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type,
+ Category
+ >
+ >
+ {
+ typedef range_detail::strided_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type,
+ Category
+ > iter_type;
+ typedef iterator_range<iter_type> super_t;
+ public:
+ template<class Difference>
+ strided_range(Difference stride, Rng& rng)
+ : super_t(make_strided_iterator(boost::begin(rng), boost::begin(rng), boost::end(rng), stride),
+ make_strided_iterator(boost::begin(rng), boost::end(rng), boost::end(rng), stride))
+ {
+ BOOST_ASSERT( stride >= 0 );
+ }
+ };
+
+ template<class Difference>
+ class strided_holder : public holder<Difference>
+ {
+ public:
+ explicit strided_holder(Difference value) : holder<Difference>(value) {}
+ };
+
+ template<class Rng, class Difference>
+ inline strided_range<Rng>
+ operator|(Rng& rng, const strided_holder<Difference>& stride)
+ {
+ return strided_range<Rng>(stride.val, rng);
+ }
+
+ template<class Rng, class Difference>
+ inline strided_range<const Rng>
+ operator|(const Rng& rng, const strided_holder<Difference>& stride)
+ {
+ return strided_range<const Rng>(stride.val, rng);
+ }
+
+ } // namespace range_detail
+
+ using range_detail::strided_range;
+
+ namespace adaptors
+ {
+
+ namespace
+ {
+ const range_detail::forwarder<range_detail::strided_holder>
+ strided = range_detail::forwarder<range_detail::strided_holder>();
+ }
+
+ template<class Range, class Difference>
+ inline strided_range<Range>
+ stride(Range& rng, Difference step)
+ {
+ return strided_range<Range>(step, rng);
+ }
+
+ template<class Range, class Difference>
+ inline strided_range<const Range>
+ stride(const Range& rng, Difference step)
+ {
+ return strided_range<const Range>(step, rng);
+ }
+
+ } // namespace 'adaptors'
+} // namespace 'boost'
+
+#endif
diff --git a/src/boost/range/adaptor/tokenized.hpp b/src/boost/range/adaptor/tokenized.hpp
new file mode 100644
index 0000000..8a7402a
--- /dev/null
+++ b/src/boost/range/adaptor/tokenized.hpp
@@ -0,0 +1,137 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
+#define BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
+
+#include <boost/regex.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+
+ template< class R >
+ struct tokenized_range :
+ public boost::iterator_range<
+ boost::regex_token_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ >
+ {
+ private:
+ typedef
+ boost::regex_token_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ regex_iter;
+
+ typedef BOOST_DEDUCED_TYPENAME regex_iter::regex_type
+ regex_type;
+
+ typedef boost::iterator_range<regex_iter>
+ base;
+
+ public:
+ template< class Regex, class Submatch, class Flag >
+ tokenized_range( R& r, const Regex& re, const Submatch& sub, Flag f )
+ : base( regex_iter( boost::begin(r), boost::end(r),
+ regex_type(re), sub, f ),
+ regex_iter() )
+ { }
+ };
+
+ template< class T, class U, class V >
+ struct regex_holder
+ {
+ const T& re;
+ const U& sub;
+ V f;
+
+ regex_holder( const T& rex, const U& subm, V flag ) :
+ re(rex), sub(subm), f(flag)
+ { }
+ private:
+ // Not assignable
+ void operator=(const regex_holder&);
+ };
+
+ struct regex_forwarder
+ {
+ template< class Regex >
+ regex_holder<Regex,int,regex_constants::match_flag_type>
+ operator()( const Regex& re,
+ int submatch = 0,
+ regex_constants::match_flag_type f =
+ regex_constants::match_default ) const
+ {
+ return regex_holder<Regex,int,
+ regex_constants::match_flag_type>( re, submatch, f );
+ }
+
+ template< class Regex, class Submatch >
+ regex_holder<Regex,Submatch,regex_constants::match_flag_type>
+ operator()( const Regex& re,
+ const Submatch& sub,
+ regex_constants::match_flag_type f =
+ regex_constants::match_default ) const
+ {
+ return regex_holder<Regex,Submatch,
+ regex_constants::match_flag_type>( re, sub, f );
+ }
+ };
+
+ template< class BidirectionalRng, class R, class S, class F >
+ inline tokenized_range<BidirectionalRng>
+ operator|( BidirectionalRng& r,
+ const regex_holder<R,S,F>& f )
+ {
+ return tokenized_range<BidirectionalRng>( r, f.re, f.sub, f.f );
+ }
+
+ template< class BidirectionalRng, class R, class S, class F >
+ inline tokenized_range<const BidirectionalRng>
+ operator|( const BidirectionalRng& r,
+ const regex_holder<R,S,F>& f )
+ {
+ return tokenized_range<const BidirectionalRng>( r, f.re, f.sub, f.f );
+ }
+
+ } // 'range_detail'
+
+ using range_detail::tokenized_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::regex_forwarder tokenized =
+ range_detail::regex_forwarder();
+ }
+
+ template<class BidirectionalRange, class Regex, class Submatch, class Flag>
+ inline tokenized_range<BidirectionalRange>
+ tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
+ {
+ return tokenized_range<BidirectionalRange>(rng, reg, sub, f);
+ }
+
+ template<class BidirectionalRange, class Regex, class Submatch, class Flag>
+ inline tokenized_range<const BidirectionalRange>
+ tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
+ {
+ return tokenized_range<const BidirectionalRange>(rng, reg, sub, f);
+ }
+ } // 'adaptors'
+
+}
+
+#endif
diff --git a/src/boost/range/adaptor/transformed.hpp b/src/boost/range/adaptor/transformed.hpp
new file mode 100644
index 0000000..96d2dab
--- /dev/null
+++ b/src/boost/range/adaptor/transformed.hpp
@@ -0,0 +1,104 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
+#define BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP
+
+#include <boost/range/adaptor/argument_fwd.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/utility/result_of.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+
+ template< class F, class R >
+ struct transformed_range :
+ public boost::iterator_range<
+ boost::transform_iterator< F,
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ >
+ {
+ private:
+ typedef boost::iterator_range<
+ boost::transform_iterator< F,
+ BOOST_DEDUCED_TYPENAME range_iterator<R>::type
+ >
+ >
+ base;
+
+ public:
+ typedef F transform_fn_type;
+ typedef R source_range_type;
+
+ transformed_range( F f, R& r )
+ : base( boost::make_transform_iterator( boost::begin(r), f ),
+ boost::make_transform_iterator( boost::end(r), f ) )
+
+ { }
+ };
+
+ template< class T >
+ struct transform_holder : holder<T>
+ {
+ transform_holder( T r ) : holder<T>(r)
+ { }
+ };
+
+ template< class InputRng, class UnaryFunction >
+ inline transformed_range<UnaryFunction,InputRng>
+ operator|( InputRng& r,
+ const transform_holder<UnaryFunction>& f )
+ {
+ return transformed_range<UnaryFunction,InputRng>( f.val, r );
+ }
+
+ template< class InputRng, class UnaryFunction >
+ inline transformed_range<UnaryFunction, const InputRng>
+ operator|( const InputRng& r,
+ const transform_holder<UnaryFunction>& f )
+ {
+ return transformed_range<UnaryFunction, const InputRng>( f.val, r );
+ }
+
+ } // 'range_detail'
+
+ using range_detail::transformed_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::forwarder<range_detail::transform_holder>
+ transformed =
+ range_detail::forwarder<range_detail::transform_holder>();
+ }
+
+ template<class UnaryFunction, class InputRange>
+ inline transformed_range<UnaryFunction, InputRange>
+ transform(InputRange& rng, UnaryFunction fn)
+ {
+ return transformed_range<UnaryFunction, InputRange>(fn, rng);
+ }
+
+ template<class UnaryFunction, class InputRange>
+ inline transformed_range<UnaryFunction, const InputRange>
+ transform(const InputRange& rng, UnaryFunction fn)
+ {
+ return transformed_range<UnaryFunction, const InputRange>(fn, rng);
+ }
+ } // 'adaptors'
+
+}
+
+#endif
diff --git a/src/boost/range/adaptor/type_erased.hpp b/src/boost/range/adaptor/type_erased.hpp
new file mode 100644
index 0000000..80bc712
--- /dev/null
+++ b/src/boost/range/adaptor/type_erased.hpp
@@ -0,0 +1,184 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
+#define BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED
+
+#include <boost/range/reference.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/range/any_range.hpp>
+#include <boost/cast.hpp>
+
+namespace boost
+{
+ namespace adaptors
+ {
+ template<
+ class Value = use_default
+ , class Traversal = use_default
+ , class Reference = use_default
+ , class Difference = use_default
+ , class Buffer = use_default
+ >
+ struct type_erased
+ {
+ };
+
+ template<
+ class SinglePassRange
+ , class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ typename any_range_type_generator<
+ SinglePassRange
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type
+ operator|(SinglePassRange& rng,
+ type_erased<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >)
+ {
+ typedef typename any_range_type_generator<
+ SinglePassRange
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type range_type;
+ return range_type(boost::begin(rng), boost::end(rng));
+ }
+
+ template<
+ class SinglePassRange
+ , class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ typename any_range_type_generator<
+ const SinglePassRange
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type
+ operator|(const SinglePassRange& rng,
+ type_erased<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >)
+ {
+ typedef typename any_range_type_generator<
+ const SinglePassRange
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type range_type;
+ return range_type(boost::begin(rng), boost::end(rng));
+ }
+
+ template<
+ class SinglePassRange
+ , class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ typename any_range_type_generator<
+ SinglePassRange
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type
+ type_erase(SinglePassRange& rng
+ , type_erased<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ > = type_erased<>()
+ )
+ {
+ typedef typename any_range_type_generator<
+ SinglePassRange
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type range_type;
+
+ return range_type(boost::begin(rng), boost::end(rng));
+ }
+
+ template<
+ class SinglePassRange
+ , class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ typename any_range_type_generator<
+ const SinglePassRange
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type
+ type_erase(const SinglePassRange& rng
+ , type_erased<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ > = type_erased<>()
+ )
+ {
+ typedef typename any_range_type_generator<
+ const SinglePassRange
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type range_type;
+
+ return range_type(boost::begin(rng), boost::end(rng));
+ }
+ }
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/adaptor/uniqued.hpp b/src/boost/range/adaptor/uniqued.hpp
new file mode 100644
index 0000000..40c8249
--- /dev/null
+++ b/src/boost/range/adaptor/uniqued.hpp
@@ -0,0 +1,90 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
+#define BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
+
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+
+namespace boost
+{
+
+ namespace range_detail
+ {
+ struct unique_forwarder { };
+
+ struct unique_not_equal_to
+ {
+ typedef bool result_type;
+
+ template< class T >
+ bool operator()( const T& l, const T& r ) const
+ {
+ return !(l == r);
+ }
+ };
+
+ template<class ForwardRng>
+ class uniqued_range : public adjacent_filtered_range<unique_not_equal_to, ForwardRng, true>
+ {
+ typedef adjacent_filtered_range<unique_not_equal_to, ForwardRng, true> base;
+ public:
+ explicit uniqued_range(ForwardRng& rng)
+ : base(unique_not_equal_to(), rng)
+ {
+ }
+ };
+
+ template< class ForwardRng >
+ inline uniqued_range<ForwardRng>
+ operator|( ForwardRng& r,
+ unique_forwarder )
+ {
+ return uniqued_range<ForwardRng>(r);
+ }
+
+ template< class ForwardRng >
+ inline uniqued_range<const ForwardRng>
+ operator|( const ForwardRng& r,
+ unique_forwarder )
+ {
+ return uniqued_range<const ForwardRng>(r);
+ }
+
+ } // 'range_detail'
+
+ using range_detail::uniqued_range;
+
+ namespace adaptors
+ {
+ namespace
+ {
+ const range_detail::unique_forwarder uniqued =
+ range_detail::unique_forwarder();
+ }
+
+ template<class ForwardRange>
+ inline uniqued_range<ForwardRange>
+ unique(ForwardRange& rng)
+ {
+ return uniqued_range<ForwardRange>(rng);
+ }
+
+ template<class ForwardRange>
+ inline uniqued_range<const ForwardRange>
+ unique(const ForwardRange& rng)
+ {
+ return uniqued_range<const ForwardRange>(rng);
+ }
+ } // 'adaptors'
+
+}
+
+#endif
diff --git a/src/boost/range/adaptors.hpp b/src/boost/range/adaptors.hpp
new file mode 100644
index 0000000..92062a9
--- /dev/null
+++ b/src/boost/range/adaptors.hpp
@@ -0,0 +1,30 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2007.
+// Copyright Thorsten Ottosen 2006.
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ADAPTORS_HPP
+#define BOOST_RANGE_ADAPTORS_HPP
+
+#include <boost/range/adaptor/adjacent_filtered.hpp>
+#include <boost/range/adaptor/copied.hpp>
+#include <boost/range/adaptor/filtered.hpp>
+#include <boost/range/adaptor/indexed.hpp>
+#include <boost/range/adaptor/indirected.hpp>
+#include <boost/range/adaptor/map.hpp>
+#include <boost/range/adaptor/replaced.hpp>
+#include <boost/range/adaptor/replaced_if.hpp>
+#include <boost/range/adaptor/reversed.hpp>
+#include <boost/range/adaptor/sliced.hpp>
+#include <boost/range/adaptor/strided.hpp>
+#include <boost/range/adaptor/tokenized.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/adaptor/uniqued.hpp>
+
+#endif
diff --git a/src/boost/range/algorithm.hpp b/src/boost/range/algorithm.hpp
new file mode 100644
index 0000000..b7d8dd7
--- /dev/null
+++ b/src/boost/range/algorithm.hpp
@@ -0,0 +1,104 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file algorithm.hpp
+/// Includes the range-based versions of the algorithms in the
+/// C++ standard header file <algorithm>
+//
+/////////////////////////////////////////////////////////////////////////////
+
+// Copyright 2009 Neil Groves.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Acknowledgements:
+// This code uses combinations of ideas, techniques and code snippets
+// from: Thorsten Ottosen, Eric Niebler, Jeremy Siek,
+// and Vladimir Prus'
+//
+// The original mutating algorithms that served as the first version
+// were originally written by Vladimir Prus'
+// <ghost at cs.msu.su> code from Boost Wiki
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009
+#define BOOST_RANGE_ALGORITHM_HPP_INCLUDED_01012009
+
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/next_prior.hpp>
+#include <algorithm>
+
+// Non-mutating algorithms
+#include <boost/range/algorithm/adjacent_find.hpp>
+#include <boost/range/algorithm/count.hpp>
+#include <boost/range/algorithm/count_if.hpp>
+#include <boost/range/algorithm/equal.hpp>
+#include <boost/range/algorithm/for_each.hpp>
+#include <boost/range/algorithm/find.hpp>
+#include <boost/range/algorithm/find_end.hpp>
+#include <boost/range/algorithm/find_first_of.hpp>
+#include <boost/range/algorithm/find_if.hpp>
+#include <boost/range/algorithm/lexicographical_compare.hpp>
+#include <boost/range/algorithm/mismatch.hpp>
+#include <boost/range/algorithm/search.hpp>
+#include <boost/range/algorithm/search_n.hpp>
+
+// Mutating algorithms
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/range/algorithm/copy_backward.hpp>
+#include <boost/range/algorithm/fill.hpp>
+#include <boost/range/algorithm/fill_n.hpp>
+#include <boost/range/algorithm/generate.hpp>
+#include <boost/range/algorithm/inplace_merge.hpp>
+#include <boost/range/algorithm/merge.hpp>
+#include <boost/range/algorithm/nth_element.hpp>
+#include <boost/range/algorithm/partial_sort.hpp>
+#include <boost/range/algorithm/partial_sort_copy.hpp>
+#include <boost/range/algorithm/partition.hpp>
+#include <boost/range/algorithm/random_shuffle.hpp>
+#include <boost/range/algorithm/remove.hpp>
+#include <boost/range/algorithm/remove_copy.hpp>
+#include <boost/range/algorithm/remove_copy_if.hpp>
+#include <boost/range/algorithm/remove_if.hpp>
+#include <boost/range/algorithm/replace.hpp>
+#include <boost/range/algorithm/replace_copy.hpp>
+#include <boost/range/algorithm/replace_copy_if.hpp>
+#include <boost/range/algorithm/replace_if.hpp>
+#include <boost/range/algorithm/reverse.hpp>
+#include <boost/range/algorithm/reverse_copy.hpp>
+#include <boost/range/algorithm/rotate.hpp>
+#include <boost/range/algorithm/rotate_copy.hpp>
+#include <boost/range/algorithm/sort.hpp>
+#include <boost/range/algorithm/stable_partition.hpp>
+#include <boost/range/algorithm/stable_sort.hpp>
+#include <boost/range/algorithm/transform.hpp>
+#include <boost/range/algorithm/unique.hpp>
+#include <boost/range/algorithm/unique_copy.hpp>
+
+// Binary search
+#include <boost/range/algorithm/binary_search.hpp>
+#include <boost/range/algorithm/equal_range.hpp>
+#include <boost/range/algorithm/lower_bound.hpp>
+#include <boost/range/algorithm/upper_bound.hpp>
+
+// Set operations of sorted ranges
+#include <boost/range/algorithm/set_algorithm.hpp>
+
+// Heap operations
+#include <boost/range/algorithm/heap_algorithm.hpp>
+
+// Minimum and Maximum
+#include <boost/range/algorithm/max_element.hpp>
+#include <boost/range/algorithm/min_element.hpp>
+
+// Permutations
+#include <boost/range/algorithm/permutation.hpp>
+
+#endif // include guard
+
diff --git a/src/boost/range/algorithm/adjacent_find.hpp b/src/boost/range/algorithm/adjacent_find.hpp
new file mode 100644
index 0000000..1b88dae
--- /dev/null
+++ b/src/boost/range/algorithm/adjacent_find.hpp
@@ -0,0 +1,125 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ADJACENT_FIND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function adjacent_find
+///
+/// range-based version of the adjacent_find std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< typename ForwardRange >
+inline typename range_iterator<ForwardRange>::type
+adjacent_find(ForwardRange & rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return std::adjacent_find(boost::begin(rng),boost::end(rng));
+}
+
+/// \overload
+template< typename ForwardRange >
+inline typename range_iterator<const ForwardRange>::type
+adjacent_find(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return std::adjacent_find(boost::begin(rng),boost::end(rng));
+}
+
+/// \overload
+template< typename ForwardRange, typename BinaryPredicate >
+inline typename range_iterator<ForwardRange>::type
+adjacent_find(ForwardRange & rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ typename range_value<ForwardRange>::type,
+ typename range_value<ForwardRange>::type>));
+ return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
+}
+
+/// \overload
+template< typename ForwardRange, typename BinaryPredicate >
+inline typename range_iterator<const ForwardRange>::type
+adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ typename range_value<const ForwardRange>::type,
+ typename range_value<const ForwardRange>::type>));
+ return std::adjacent_find(boost::begin(rng),boost::end(rng),pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, typename ForwardRange >
+inline typename range_return<ForwardRange,re>::type
+adjacent_find(ForwardRange & rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_return<ForwardRange,re>::
+ pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange >
+inline typename range_return<const ForwardRange,re>::type
+adjacent_find(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_return<const ForwardRange,re>::
+ pack(std::adjacent_find(boost::begin(rng),boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
+inline typename range_return<ForwardRange,re>::type
+adjacent_find(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ typename range_value<ForwardRange>::type,
+ typename range_value<ForwardRange>::type>));
+ return range_return<ForwardRange,re>::
+ pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, typename ForwardRange, typename BinaryPredicate >
+inline typename range_return<const ForwardRange,re>::type
+adjacent_find(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_return<const ForwardRange,re>::
+ pack(std::adjacent_find(boost::begin(rng),boost::end(rng),pred),
+ rng);
+}
+
+ } // namespace range
+ using range::adjacent_find;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/binary_search.hpp b/src/boost/range/algorithm/binary_search.hpp
new file mode 100644
index 0000000..bb64ec8
--- /dev/null
+++ b/src/boost/range/algorithm/binary_search.hpp
@@ -0,0 +1,49 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_BINARY_SEARCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function binary_search
+///
+/// range-based version of the binary_search std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange, class Value>
+inline bool binary_search(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::binary_search(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class BinaryPredicate>
+inline bool binary_search(const ForwardRange& rng, const Value& val,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::binary_search(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+ } // namespace range
+ using range::binary_search;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/copy.hpp b/src/boost/range/algorithm/copy.hpp
new file mode 100644
index 0000000..f15b31f
--- /dev/null
+++ b/src/boost/range/algorithm/copy.hpp
@@ -0,0 +1,41 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function copy
+///
+/// range-based version of the copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+template< class SinglePassRange, class OutputIterator >
+inline OutputIterator copy(const SinglePassRange& rng, OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::copy(boost::begin(rng),boost::end(rng),out);
+}
+
+ } // namespace range
+ using range::copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/copy_backward.hpp b/src/boost/range/algorithm/copy_backward.hpp
new file mode 100644
index 0000000..c95c6f1
--- /dev/null
+++ b/src/boost/range/algorithm/copy_backward.hpp
@@ -0,0 +1,43 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COPY_BACKWARD_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function copy_backward
+///
+/// range-based version of the copy_backwards std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre BidirectionalTraversalWriteableIterator is a model of the BidirectionalIteratorConcept
+/// \pre BidirectionalTraversalWriteableIterator is a model of the WriteableIteratorConcept
+template< class BidirectionalRange, class BidirectionalTraversalWriteableIterator >
+inline BidirectionalTraversalWriteableIterator
+copy_backward(const BidirectionalRange& rng,
+ BidirectionalTraversalWriteableIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::copy_backward(boost::begin(rng), boost::end(rng), out);
+}
+
+ } // namespace range
+ using range::copy_backward;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/count.hpp b/src/boost/range/algorithm/count.hpp
new file mode 100644
index 0000000..8316ce0
--- /dev/null
+++ b/src/boost/range/algorithm/count.hpp
@@ -0,0 +1,50 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function count
+///
+/// range-based version of the count std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type
+count(SinglePassRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::count(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange const>::type
+count(const SinglePassRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::count(boost::begin(rng), boost::end(rng), val);
+}
+
+ } // namespace range
+ using range::count;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/count_if.hpp b/src/boost/range/algorithm/count_if.hpp
new file mode 100644
index 0000000..ae17b0e
--- /dev/null
+++ b/src/boost/range/algorithm/count_if.hpp
@@ -0,0 +1,51 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COUNT_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function count_if
+///
+/// range-based version of the count_if std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_difference<SinglePassRange>::type
+count_if(SinglePassRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::count_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_difference<const SinglePassRange>::type
+count_if(const SinglePassRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::count_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+ } // namespace range
+ using range::count_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/equal.hpp b/src/boost/range/algorithm/equal.hpp
new file mode 100644
index 0000000..4472bb1
--- /dev/null
+++ b/src/boost/range/algorithm/equal.hpp
@@ -0,0 +1,198 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009.
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <iterator>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ // An implementation of equality comparison that is optimized for iterator
+ // traversal categories less than RandomAccessTraversal.
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class IteratorCategoryTag1,
+ class IteratorCategoryTag2 >
+ inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ IteratorCategoryTag1,
+ IteratorCategoryTag2 )
+ {
+ while (true)
+ {
+ // If we have reached the end of the left range then this is
+ // the end of the loop. They are equal if and only if we have
+ // simultaneously reached the end of the right range.
+ if (first1 == last1)
+ return first2 == last2;
+
+ // If we have reached the end of the right range at this line
+ // it indicates that the right range is shorter than the left
+ // and hence the result is false.
+ if (first2 == last2)
+ return false;
+
+ // continue looping if and only if the values are equal
+ if (*first1 != *first2)
+ break;
+
+ ++first1;
+ ++first2;
+ }
+
+ // Reaching this line in the algorithm indicates that a value
+ // inequality has been detected.
+ return false;
+ }
+
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class IteratorCategoryTag1,
+ class IteratorCategoryTag2,
+ class BinaryPredicate >
+ inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ BinaryPredicate pred,
+ IteratorCategoryTag1,
+ IteratorCategoryTag2 )
+ {
+ while (true)
+ {
+ // If we have reached the end of the left range then this is
+ // the end of the loop. They are equal if and only if we have
+ // simultaneously reached the end of the right range.
+ if (first1 == last1)
+ return first2 == last2;
+
+ // If we have reached the end of the right range at this line
+ // it indicates that the right range is shorter than the left
+ // and hence the result is false.
+ if (first2 == last2)
+ return false;
+
+ // continue looping if and only if the values are equal
+ if (!pred(*first1, *first2))
+ break;
+
+ ++first1;
+ ++first2;
+ }
+
+ // Reaching this line in the algorithm indicates that a value
+ // inequality has been detected.
+ return false;
+ }
+
+ // An implementation of equality comparison that is optimized for
+ // random access iterators.
+ template< class RandomAccessTraversalReadableIterator1,
+ class RandomAccessTraversalReadableIterator2 >
+ inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
+ RandomAccessTraversalReadableIterator1 last1,
+ RandomAccessTraversalReadableIterator2 first2,
+ RandomAccessTraversalReadableIterator2 last2,
+ std::random_access_iterator_tag,
+ std::random_access_iterator_tag )
+ {
+ return ((last1 - first1) == (last2 - first2))
+ && std::equal(first1, last1, first2);
+ }
+
+ template< class RandomAccessTraversalReadableIterator1,
+ class RandomAccessTraversalReadableIterator2,
+ class BinaryPredicate >
+ inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
+ RandomAccessTraversalReadableIterator1 last1,
+ RandomAccessTraversalReadableIterator2 first2,
+ RandomAccessTraversalReadableIterator2 last2,
+ BinaryPredicate pred )
+ {
+ return ((last1 - first1) == (last2 - first2))
+ && std::equal(first1, last1, first2, pred);
+ }
+
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2 >
+ inline bool equal( SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2 )
+ {
+ BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
+ BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
+
+ return equal_impl(first1, last1, first2, last2, tag1, tag2);
+ }
+
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class BinaryPredicate >
+ inline bool equal( SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ BinaryPredicate pred )
+ {
+ BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
+ BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
+
+ return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
+ }
+
+ } // namespace range_detail
+
+ namespace range
+ {
+
+ /// \brief template function equal
+ ///
+ /// range-based version of the equal std algorithm
+ ///
+ /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+ /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+ /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+ template< class SinglePassRange1, class SinglePassRange2 >
+ inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::equal(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2) );
+ }
+
+ /// \overload
+ template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+ inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
+ BinaryPredicate pred )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::equal(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2),
+ pred);
+ }
+
+ } // namespace range
+ using ::boost::range::equal;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/equal_range.hpp b/src/boost/range/algorithm/equal_range.hpp
new file mode 100644
index 0000000..4aa4a54
--- /dev/null
+++ b/src/boost/range/algorithm/equal_range.hpp
@@ -0,0 +1,80 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EQUAL_RANGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function equal_range
+///
+/// range-based version of the equal_range std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre SortPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange, class Value>
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+ >
+equal_range(ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::equal_range(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value>
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+ >
+equal_range(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::equal_range(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class SortPredicate>
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+ >
+equal_range(ForwardRange& rng, const Value& val, SortPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template<class ForwardRange, class Value, class SortPredicate>
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+ >
+equal_range(const ForwardRange& rng, const Value& val, SortPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::equal_range(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+ } // namespace range
+ using range::equal_range;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/fill.hpp b/src/boost/range/algorithm/fill.hpp
new file mode 100644
index 0000000..95231a8
--- /dev/null
+++ b/src/boost/range/algorithm/fill.hpp
@@ -0,0 +1,49 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FILL_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function fill
+///
+/// range-based version of the fill std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline ForwardRange& fill(ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::fill(boost::begin(rng), boost::end(rng), val);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline const ForwardRange& fill(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::fill(boost::begin(rng), boost::end(rng), val);
+ return rng;
+}
+
+ } // namespace range
+ using range::fill;
+}
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/fill_n.hpp b/src/boost/range/algorithm/fill_n.hpp
new file mode 100644
index 0000000..02a0c2a
--- /dev/null
+++ b/src/boost/range/algorithm/fill_n.hpp
@@ -0,0 +1,53 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FILL_N_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function fill_n
+///
+/// range-based version of the fill_n std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre n <= std::distance(boost::begin(rng), boost::end(rng))
+template< class ForwardRange, class Size, class Value >
+inline ForwardRange& fill_n(ForwardRange& rng, Size n, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
+ std::fill_n(boost::begin(rng), n, val);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Size, class Value >
+inline const ForwardRange& fill_n(const ForwardRange& rng, Size n, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ BOOST_ASSERT( static_cast<Size>(std::distance(boost::begin(rng), boost::end(rng))) >= n );
+ std::fill_n(boost::begin(rng), n, val);
+ return rng;
+}
+
+ } // namespace range
+ using range::fill_n;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/find.hpp b/src/boost/range/algorithm/find.hpp
new file mode 100644
index 0000000..72c5cf1
--- /dev/null
+++ b/src/boost/range/algorithm/find.hpp
@@ -0,0 +1,80 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function find
+///
+/// range-based version of the find std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
+>::type
+find( SinglePassRange& rng, const Value& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::find(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
+find( const SinglePassRange& rng, const Value& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::find(boost::begin(rng), boost::end(rng), val);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange>,
+ BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
+>::type
+find( SinglePassRange& rng, const Value& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return range_return<SinglePassRange,re>::
+ pack(std::find(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
+find( const SinglePassRange& rng, const Value& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return range_return<const SinglePassRange,re>::
+ pack(std::find(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+ } // namespace range
+ using range::find;
+}
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/find_end.hpp b/src/boost/range/algorithm/find_end.hpp
new file mode 100644
index 0000000..757e999
--- /dev/null
+++ b/src/boost/range/algorithm/find_end.hpp
@@ -0,0 +1,152 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_END_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function find_end
+///
+/// range-based version of the find_end std algorithm
+///
+/// \pre ForwardRange1 is a model of the ForwardRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange1>,
+ BOOST_DEDUCED_TYPENAME range_iterator< ForwardRange1 >::type
+>::type
+find_end(ForwardRange1 & rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_end(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator< const ForwardRange1 >::type
+find_end(const ForwardRange1 & rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_end(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange1>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+>::type
+find_end(ForwardRange1 & rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_end(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_end(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange1>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<ForwardRange1,re>::
+ pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<const ForwardRange1,re>::
+ pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange1>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+>::type
+find_end(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<ForwardRange1,re>::
+ pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+find_end(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<const ForwardRange1,re>::
+ pack(std::find_end(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred),
+ rng1);
+}
+
+ } // namespace range
+ using range::find_end;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/find_first_of.hpp b/src/boost/range/algorithm/find_first_of.hpp
new file mode 100644
index 0000000..4cb5989
--- /dev/null
+++ b/src/boost/range/algorithm/find_first_of.hpp
@@ -0,0 +1,155 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_FIRST_OF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function find_first_of
+///
+/// range-based version of the find_first_of std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange1>,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange1>,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, ForwardRange2 const & rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return std::find_first_of(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+// range return overloads
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange1>,
+ BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
+>::type
+find_first_of(SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<SinglePassRange1,re>::
+ pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
+find_first_of(const SinglePassRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<const SinglePassRange1,re>::
+ pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange1>,
+ BOOST_DEDUCED_TYPENAME range_return<SinglePassRange1,re>::type
+>::type
+find_first_of(SinglePassRange1 & rng1, const ForwardRange2& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<SinglePassRange1,re>::
+ pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange1,re>::type
+find_first_of(const SinglePassRange1 & rng1, const ForwardRange2& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+
+ return range_return<const SinglePassRange1,re>::
+ pack(std::find_first_of(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred),
+ rng1);
+}
+
+ } // namespace range
+ using range::find_first_of;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/find_if.hpp b/src/boost/range/algorithm/find_if.hpp
new file mode 100644
index 0000000..2d1926d
--- /dev/null
+++ b/src/boost/range/algorithm/find_if.hpp
@@ -0,0 +1,81 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FIND_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function find_if
+///
+/// range-based version of the find_if std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type
+>::type
+find_if( SinglePassRange& rng, UnaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::find_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type
+find_if( const SinglePassRange& rng, UnaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::find_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<SinglePassRange>,
+ BOOST_DEDUCED_TYPENAME range_return<SinglePassRange,re>::type
+>::type
+find_if( SinglePassRange& rng, UnaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return range_return<SinglePassRange,re>::
+ pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class SinglePassRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const SinglePassRange,re>::type
+find_if( const SinglePassRange& rng, UnaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return range_return<const SinglePassRange,re>::
+ pack(std::find_if(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+ } // namespace range
+ using range::find_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/for_each.hpp b/src/boost/range/algorithm/for_each.hpp
new file mode 100644
index 0000000..4f5108d
--- /dev/null
+++ b/src/boost/range/algorithm/for_each.hpp
@@ -0,0 +1,109 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_FOR_EACH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/ref.hpp>
+#include <algorithm>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+#include <xutility>
+#endif
+
+namespace boost
+{
+ namespace range
+ {
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+ namespace for_each_detail
+ {
+ template<typename Iterator, typename UnaryFunction>
+ inline UnaryFunction
+ for_each_impl(Iterator first, Iterator last, UnaryFunction fun,
+ typename enable_if<
+ is_reference_wrapper<UnaryFunction>,
+ void
+ >::type* = 0)
+ {
+ typedef typename std::_Get_unchecked_type<Iterator>::type
+ unchecked_iterator;
+
+ unchecked_iterator unchecked_last = std::_Unchecked(last);
+ for (unchecked_iterator unchecked_first = std::_Unchecked(first); first != last; ++first)
+ fun.get()(*unchecked_first);
+
+ return fun;
+ }
+
+ template<typename Iterator, typename UnaryFunction>
+ inline UnaryFunction
+ for_each_impl(Iterator first, Iterator last, UnaryFunction fn,
+ typename disable_if<
+ is_reference_wrapper<UnaryFunction>,
+ void
+ >::type* = 0)
+ {
+ return std::for_each<Iterator, UnaryFunction>(first, last, fn);
+ }
+ }
+#endif
+
+/// \brief template function for_each
+///
+/// range-based version of the for_each std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre UnaryFunction is a model of the UnaryFunctionConcept
+template< class SinglePassRange, class UnaryFunction >
+inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+ return for_each_detail::for_each_impl<
+ typename range_iterator<SinglePassRange>::type,
+ UnaryFunction
+ >(boost::begin(rng), boost::end(rng), fun);
+#else
+ return std::for_each<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type,
+ UnaryFunction
+ >(boost::begin(rng),boost::end(rng),fun);
+#endif
+}
+
+/// \overload
+template< class SinglePassRange, class UnaryFunction >
+inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+ return for_each_detail::for_each_impl<
+ typename range_iterator<const SinglePassRange>::type,
+ UnaryFunction
+ >(boost::begin(rng), boost::end(rng), fun);
+#else
+ return std::for_each<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type,
+ UnaryFunction
+ >(boost::begin(rng), boost::end(rng), fun);
+#endif
+}
+
+ } // namespace range
+ using range::for_each;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/generate.hpp b/src/boost/range/algorithm/generate.hpp
new file mode 100644
index 0000000..324412c
--- /dev/null
+++ b/src/boost/range/algorithm/generate.hpp
@@ -0,0 +1,49 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_GENERATE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+/// \brief template function generate
+///
+/// range-based version of the generate std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Generator is a model of the UnaryFunctionConcept
+template< class ForwardRange, class Generator >
+inline ForwardRange& generate( ForwardRange& rng, Generator gen )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::generate(boost::begin(rng), boost::end(rng), gen);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Generator >
+inline const ForwardRange& generate( const ForwardRange& rng, Generator gen )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::generate(boost::begin(rng), boost::end(rng), gen);
+ return rng;
+}
+
+ } // namespace range
+ using range::generate;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/heap_algorithm.hpp b/src/boost/range/algorithm/heap_algorithm.hpp
new file mode 100644
index 0000000..584920d
--- /dev/null
+++ b/src/boost/range/algorithm/heap_algorithm.hpp
@@ -0,0 +1,194 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_HEAP_ALGORITHM_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function push_heap
+///
+/// range-based version of the push_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& push_heap(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::push_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& push_heap(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::push_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& push_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& push_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::push_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \brief template function pop_heap
+///
+/// range-based version of the pop_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& pop_heap(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::pop_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::pop_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& pop_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& pop_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::pop_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \brief template function make_heap
+///
+/// range-based version of the make_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& make_heap(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::make_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& make_heap(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::make_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& make_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& make_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::make_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \brief template function sort_heap
+///
+/// range-based version of the sort_heap std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& sort_heap(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::sort_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::sort_heap(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline RandomAccessRange& sort_heap(RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Compare>
+inline const RandomAccessRange& sort_heap(const RandomAccessRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::sort_heap(boost::begin(rng), boost::end(rng), comp_pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::push_heap;
+ using range::pop_heap;
+ using range::make_heap;
+ using range::sort_heap;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/inplace_merge.hpp b/src/boost/range/algorithm/inplace_merge.hpp
new file mode 100644
index 0000000..dfadbaa
--- /dev/null
+++ b/src/boost/range/algorithm/inplace_merge.hpp
@@ -0,0 +1,74 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_INPLACE_MERGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function inplace_merge
+///
+/// range-based version of the inplace_merge std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ std::inplace_merge(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class BidirectionalRange, class BinaryPredicate>
+inline BidirectionalRange& inplace_merge(BidirectionalRange& rng,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<BidirectionalRange>::type middle,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
+ return rng;
+}
+
+/// \overload
+template<class BidirectionalRange, class BinaryPredicate>
+inline const BidirectionalRange& inplace_merge(const BidirectionalRange& rng,
+ BOOST_DEDUCED_TYPENAME boost::range_iterator<const BidirectionalRange>::type middle,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ std::inplace_merge(boost::begin(rng), middle, boost::end(rng), pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::inplace_merge;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/lexicographical_compare.hpp b/src/boost/range/algorithm/lexicographical_compare.hpp
new file mode 100644
index 0000000..c6e4bc8
--- /dev/null
+++ b/src/boost/range/algorithm/lexicographical_compare.hpp
@@ -0,0 +1,58 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function lexicographic_compare
+///
+/// range-based version of the lexicographic_compare std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+template<class SinglePassRange1, class SinglePassRange2>
+inline bool lexicographical_compare(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::lexicographical_compare(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class BinaryPredicate>
+inline bool lexicographical_compare(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::lexicographical_compare(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+ } // namespace range
+ using range::lexicographical_compare;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/lower_bound.hpp b/src/boost/range/algorithm/lower_bound.hpp
new file mode 100644
index 0000000..cb5e639
--- /dev/null
+++ b/src/boost/range/algorithm/lower_bound.hpp
@@ -0,0 +1,124 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_LOWER_BOUND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function lower_bound
+///
+/// range-based version of the lower_bound std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+lower_bound( ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::lower_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+lower_bound( const ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::lower_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::lower_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+lower_bound( ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+lower_bound( const ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::lower_bound(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+lower_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+lower_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::lower_bound(boost::begin(rng), boost::end(rng), val, pred),
+ rng);
+}
+
+ } // namespace range
+ using range::lower_bound;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/max_element.hpp b/src/boost/range/algorithm/max_element.hpp
new file mode 100644
index 0000000..a0c1ffd
--- /dev/null
+++ b/src/boost/range/algorithm/max_element.hpp
@@ -0,0 +1,115 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function max_element
+///
+/// range-based version of the max_element std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+max_element(ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::max_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+max_element(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::max_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+max_element(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::max_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+max_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::max_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+max_element(ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ std::max_element(boost::begin(rng), boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+max_element(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ std::max_element(boost::begin(rng), boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+max_element(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ std::max_element(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+max_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ std::max_element(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+ } // namespace range
+ using range::max_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/merge.hpp b/src/boost/range/algorithm/merge.hpp
new file mode 100644
index 0000000..c81b8c7
--- /dev/null
+++ b/src/boost/range/algorithm/merge.hpp
@@ -0,0 +1,61 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MERGE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function merge
+///
+/// range-based version of the merge std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+///
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator merge(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::merge(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator merge(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::merge(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+ } // namespace range
+ using range::merge;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/min_element.hpp b/src/boost/range/algorithm/min_element.hpp
new file mode 100644
index 0000000..c966b1e
--- /dev/null
+++ b/src/boost/range/algorithm/min_element.hpp
@@ -0,0 +1,115 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function min_element
+///
+/// range-based version of the min_element std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+min_element(ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::min_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+min_element(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::min_element(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+min_element(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::min_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+min_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::min_element(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+min_element(ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ std::min_element(boost::begin(rng), boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+min_element(const ForwardRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ std::min_element(boost::begin(rng), boost::end(rng)),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+min_element(ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ std::min_element(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class ForwardRange, class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+min_element(const ForwardRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ std::min_element(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+ } // namespace range
+ using range::min_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/mismatch.hpp b/src/boost/range/algorithm/mismatch.hpp
new file mode 100644
index 0000000..2819c33
--- /dev/null
+++ b/src/boost/range/algorithm/mismatch.hpp
@@ -0,0 +1,195 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2 >
+ inline std::pair<SinglePassTraversalReadableIterator1,
+ SinglePassTraversalReadableIterator2>
+ mismatch_impl(SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2)
+ {
+ while (first1 != last1 && first2 != last2 && *first1 == *first2)
+ {
+ ++first1;
+ ++first2;
+ }
+ return std::pair<SinglePassTraversalReadableIterator1,
+ SinglePassTraversalReadableIterator2>(first1, first2);
+ }
+
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class BinaryPredicate >
+ inline std::pair<SinglePassTraversalReadableIterator1,
+ SinglePassTraversalReadableIterator2>
+ mismatch_impl(SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ BinaryPredicate pred)
+ {
+ while (first1 != last1 && first2 != last2 && pred(*first1, *first2))
+ {
+ ++first1;
+ ++first2;
+ }
+ return std::pair<SinglePassTraversalReadableIterator1,
+ SinglePassTraversalReadableIterator2>(first1, first2);
+ }
+ } // namespace range_detail
+
+ namespace range
+ {
+/// \brief template function mismatch
+///
+/// range-based version of the mismatch std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, const SinglePassRange2 & rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, SinglePassRange2 & rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2));
+}
+
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
+inline std::pair<
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type >
+mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::mismatch_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), pred);
+}
+
+ } // namespace range
+ using range::mismatch;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/nth_element.hpp b/src/boost/range/algorithm/nth_element.hpp
new file mode 100644
index 0000000..a605595
--- /dev/null
+++ b/src/boost/range/algorithm/nth_element.hpp
@@ -0,0 +1,74 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_NTH_ELEMENT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function nth_element
+///
+/// range-based version of the nth_element std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& nth_element(RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::nth_element(boost::begin(rng), nth, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::nth_element(boost::begin(rng), nth, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& nth_element(RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type nth,
+ BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& nth_element(const RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type nth,
+ BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::nth_element(boost::begin(rng), nth, boost::end(rng), sort_pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::nth_element;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/partial_sort.hpp b/src/boost/range/algorithm/partial_sort.hpp
new file mode 100644
index 0000000..d7044cd
--- /dev/null
+++ b/src/boost/range/algorithm/partial_sort.hpp
@@ -0,0 +1,76 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function partial_sort
+///
+/// range-based version of the partial_sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::partial_sort(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::partial_sort(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& partial_sort(RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type middle,
+ BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::partial_sort(boost::begin(rng), middle, boost::end(rng),
+ sort_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& partial_sort(const RandomAccessRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type middle,
+ BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::partial_sort(boost::begin(rng), middle, boost::end(rng),
+ sort_pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::partial_sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/partial_sort_copy.hpp b/src/boost/range/algorithm/partial_sort_copy.hpp
new file mode 100644
index 0000000..9129389
--- /dev/null
+++ b/src/boost/range/algorithm/partial_sort_copy.hpp
@@ -0,0 +1,82 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTIAL_SORT_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/value_type.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function partial_sort_copy
+///
+/// range-based version of the partial_sort_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre RandomAccessRange is a model of the Mutable_RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange, class RandomAccessRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange,
+ class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, RandomAccessRange& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+/// \overload
+template<class SinglePassRange, class RandomAccessRange,
+ class BinaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const RandomAccessRange>::type
+partial_sort_copy(const SinglePassRange& rng1, const RandomAccessRange& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sort_copy(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+ } // namespace range
+ using range::partial_sort_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/partition.hpp b/src/boost/range/algorithm/partition.hpp
new file mode 100644
index 0000000..b814a24
--- /dev/null
+++ b/src/boost/range/algorithm/partition.hpp
@@ -0,0 +1,74 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PARTITION__HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function partition
+///
+/// range-based version of the partition std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template<class ForwardRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+partition(ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+/// \overload
+template<class ForwardRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+partition(const ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange,
+ class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+partition(ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return boost::range_return<ForwardRange,re>::
+ pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange,
+ class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+partition(const ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return boost::range_return<const ForwardRange,re>::
+ pack(std::partition(boost::begin(rng), boost::end(rng), pred), rng);
+}
+
+ } // namespace range
+ using range::partition;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/permutation.hpp b/src/boost/range/algorithm/permutation.hpp
new file mode 100644
index 0000000..75388cc
--- /dev/null
+++ b/src/boost/range/algorithm/permutation.hpp
@@ -0,0 +1,108 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_PERMUTATION_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function next_permutation
+///
+/// range-based version of the next_permutation std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline bool next_permutation(BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::next_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline bool next_permutation(const BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::next_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool next_permutation(BidirectionalRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::next_permutation(boost::begin(rng), boost::end(rng),
+ comp_pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool next_permutation(const BidirectionalRange& rng,
+ Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::next_permutation(boost::begin(rng), boost::end(rng),
+ comp_pred);
+}
+
+/// \brief template function prev_permutation
+///
+/// range-based version of the prev_permutation std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre Compare is a model of the BinaryPredicateConcept
+template<class BidirectionalRange>
+inline bool prev_permutation(BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::prev_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline bool prev_permutation(const BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::prev_permutation(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool prev_permutation(BidirectionalRange& rng, Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::prev_permutation(boost::begin(rng), boost::end(rng),
+ comp_pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class Compare>
+inline bool prev_permutation(const BidirectionalRange& rng,
+ Compare comp_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::prev_permutation(boost::begin(rng), boost::end(rng),
+ comp_pred);
+}
+
+ } // namespace range
+ using range::next_permutation;
+ using range::prev_permutation;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/random_shuffle.hpp b/src/boost/range/algorithm/random_shuffle.hpp
new file mode 100644
index 0000000..95bbd97
--- /dev/null
+++ b/src/boost/range/algorithm/random_shuffle.hpp
@@ -0,0 +1,68 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_RANDOM_SHUFFLE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function random_shuffle
+///
+/// range-based version of the random_shuffle std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre Generator is a model of the UnaryFunctionConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& random_shuffle(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::random_shuffle(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::random_shuffle(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Generator>
+inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::random_shuffle(boost::begin(rng), boost::end(rng), gen);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class Generator>
+inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::random_shuffle(boost::begin(rng), boost::end(rng), gen);
+ return rng;
+}
+
+ } // namespace range
+ using range::random_shuffle;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/remove.hpp b/src/boost/range/algorithm/remove.hpp
new file mode 100644
index 0000000..699a7cd
--- /dev/null
+++ b/src/boost/range/algorithm/remove.hpp
@@ -0,0 +1,74 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function remove
+///
+/// range-based version of the remove std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+remove(ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::remove(boost::begin(rng),boost::end(rng),val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+remove(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::remove(boost::begin(rng),boost::end(rng),val);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+remove(ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ std::remove(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+remove(const ForwardRange& rng, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ std::remove(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+ } // namespace range
+ using range::remove;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/remove_copy.hpp b/src/boost/range/algorithm/remove_copy.hpp
new file mode 100644
index 0000000..b65747e
--- /dev/null
+++ b/src/boost/range/algorithm/remove_copy.hpp
@@ -0,0 +1,44 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function remove_copy
+///
+/// range-based version of the remove_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+/// \pre Value is a model of the EqualityComparableConcept
+/// \pre Objects of type Value can be compared for equality with objects of
+/// InputIterator's value type.
+template< class SinglePassRange, class OutputIterator, class Value >
+inline OutputIterator
+remove_copy(const SinglePassRange& rng, OutputIterator out_it, const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::remove_copy(boost::begin(rng), boost::end(rng), out_it, val);
+}
+
+ } // namespace range
+ using range::remove_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/remove_copy_if.hpp b/src/boost/range/algorithm/remove_copy_if.hpp
new file mode 100644
index 0000000..8d9c37b
--- /dev/null
+++ b/src/boost/range/algorithm/remove_copy_if.hpp
@@ -0,0 +1,38 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_COPY_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ /// \brief template function remove_copy_if
+ ///
+ /// range-based version of the remove_copy_if std algorithm
+ ///
+ /// \pre SinglePassRange is a model of the SinglePassRangeConcept
+ /// \pre OutputIterator is a model of the OutputIteratorConcept
+ /// \pre Predicate is a model of the PredicateConcept
+ /// \pre InputIterator's value type is convertible to Predicate's argument type
+ /// \pre out_it is not an iterator in the range rng
+ template< class SinglePassRange, class OutputIterator, class Predicate >
+ inline OutputIterator
+ remove_copy_if(const SinglePassRange& rng, OutputIterator out_it, Predicate pred)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::remove_copy_if(boost::begin(rng), boost::end(rng), out_it, pred);
+ }
+}
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/remove_if.hpp b/src/boost/range/algorithm/remove_if.hpp
new file mode 100644
index 0000000..a965df0
--- /dev/null
+++ b/src/boost/range/algorithm/remove_if.hpp
@@ -0,0 +1,75 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REMOVE_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function remove_if
+///
+/// range-based version of the remove_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_iterator<ForwardRange>::type
+remove_if(ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::remove_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template< class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME boost::range_iterator<const ForwardRange>::type
+remove_if(const ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::remove_if(boost::begin(rng), boost::end(rng), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+remove_if(ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::pack(
+ std::remove_if(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class UnaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+remove_if(const ForwardRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::pack(
+ std::remove_if(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+ } // namespace range
+ using range::remove_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/replace.hpp b/src/boost/range/algorithm/replace.hpp
new file mode 100644
index 0000000..44d3e4c
--- /dev/null
+++ b/src/boost/range/algorithm/replace.hpp
@@ -0,0 +1,53 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function replace
+///
+/// range-based version of the replace std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline ForwardRange&
+replace(ForwardRange& rng, const Value& what,
+ const Value& with_what)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::replace(boost::begin(rng), boost::end(rng), what, with_what);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+inline const ForwardRange&
+replace(const ForwardRange& rng, const Value& what,
+ const Value& with_what)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::replace(boost::begin(rng), boost::end(rng), what, with_what);
+ return rng;
+}
+
+ } // namespace range
+ using range::replace;
+} // namespace boost;
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/replace_copy.hpp b/src/boost/range/algorithm/replace_copy.hpp
new file mode 100644
index 0000000..0c02005
--- /dev/null
+++ b/src/boost/range/algorithm/replace_copy.hpp
@@ -0,0 +1,42 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function replace_copy
+///
+/// range-based version of the replace_copy std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class OutputIterator, class Value >
+inline OutputIterator
+replace_copy(const ForwardRange& rng, OutputIterator out_it, const Value& what,
+ const Value& with_what)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::replace_copy(boost::begin(rng), boost::end(rng), out_it,
+ what, with_what);
+}
+
+ } // namespace range
+ using range::replace_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/replace_copy_if.hpp b/src/boost/range/algorithm/replace_copy_if.hpp
new file mode 100644
index 0000000..d313151
--- /dev/null
+++ b/src/boost/range/algorithm/replace_copy_if.hpp
@@ -0,0 +1,46 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_COPY_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function replace_copy_if
+///
+/// range-based version of the replace_copy_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Predicate is a model of the PredicateConcept
+/// \pre Value is convertible to Predicate's argument type
+/// \pre Value is Assignable
+/// \pre Value is convertible to a type in OutputIterator's set of value types.
+template< class ForwardRange, class OutputIterator, class Predicate, class Value >
+inline OutputIterator
+replace_copy_if(const ForwardRange& rng, OutputIterator out_it, Predicate pred,
+ const Value& with_what)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::replace_copy_if(boost::begin(rng), boost::end(rng), out_it,
+ pred, with_what);
+}
+
+ } // namespace range
+ using range::replace_copy_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/replace_if.hpp b/src/boost/range/algorithm/replace_if.hpp
new file mode 100644
index 0000000..93d5a1f
--- /dev/null
+++ b/src/boost/range/algorithm/replace_if.hpp
@@ -0,0 +1,54 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REPLACE_IF_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function replace_if
+///
+/// range-based version of the replace_if std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template< class ForwardRange, class UnaryPredicate, class Value >
+inline ForwardRange&
+ replace_if(ForwardRange& rng, UnaryPredicate pred,
+ const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
+ return rng;
+}
+
+/// \overload
+template< class ForwardRange, class UnaryPredicate, class Value >
+inline const ForwardRange&
+ replace_if(const ForwardRange& rng, UnaryPredicate pred,
+ const Value& val)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::replace_if(boost::begin(rng), boost::end(rng), pred, val);
+ return rng;
+}
+
+ } // namespace range
+ using range::replace_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/reverse.hpp b/src/boost/range/algorithm/reverse.hpp
new file mode 100644
index 0000000..20a7eb1
--- /dev/null
+++ b/src/boost/range/algorithm/reverse.hpp
@@ -0,0 +1,50 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REVERSE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function reverse
+///
+/// range-based version of the reverse std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+template<class BidirectionalRange>
+inline BidirectionalRange& reverse(BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ std::reverse(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class BidirectionalRange>
+inline const BidirectionalRange& reverse(const BidirectionalRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ std::reverse(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+ } // namespace range
+ using range::reverse;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/reverse_copy.hpp b/src/boost/range/algorithm/reverse_copy.hpp
new file mode 100644
index 0000000..f1990ad
--- /dev/null
+++ b/src/boost/range/algorithm/reverse_copy.hpp
@@ -0,0 +1,40 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_REVERSE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/iterator/iterator_concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function reverse_copy
+///
+/// range-based version of the reverse_copy std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+template<class BidirectionalRange, class OutputIterator>
+inline OutputIterator reverse_copy(const BidirectionalRange& rng, OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::reverse_copy(boost::begin(rng), boost::end(rng), out);
+}
+
+ } // namespace range
+ using range::reverse_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/rotate.hpp b/src/boost/range/algorithm/rotate.hpp
new file mode 100644
index 0000000..ca4b223
--- /dev/null
+++ b/src/boost/range/algorithm/rotate.hpp
@@ -0,0 +1,51 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ROTATE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function rotate
+///
+/// range-based version of the rotate std algorithm
+///
+/// \pre Rng meets the requirements for a Forward range
+template<class ForwardRange>
+inline ForwardRange& rotate(ForwardRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ std::rotate(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class ForwardRange>
+inline const ForwardRange& rotate(const ForwardRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ std::rotate(boost::begin(rng), middle, boost::end(rng));
+ return rng;
+}
+
+ } // namespace range
+ using range::rotate;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/rotate_copy.hpp b/src/boost/range/algorithm/rotate_copy.hpp
new file mode 100644
index 0000000..0409ac5
--- /dev/null
+++ b/src/boost/range/algorithm/rotate_copy.hpp
@@ -0,0 +1,44 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_ROTATE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+ /// \brief template function rotate
+ ///
+ /// range-based version of the rotate std algorithm
+ ///
+ /// \pre Rng meets the requirements for a Forward range
+ template<typename ForwardRange, typename OutputIterator>
+ inline OutputIterator rotate_copy(
+ const ForwardRange& rng,
+ BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type middle,
+ OutputIterator target
+ )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::rotate_copy(boost::begin(rng), middle, boost::end(rng), target);
+ }
+
+ } // namespace range
+ using range::rotate_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/search.hpp b/src/boost/range/algorithm/search.hpp
new file mode 100644
index 0000000..28cc6e6
--- /dev/null
+++ b/src/boost/range/algorithm/search.hpp
@@ -0,0 +1,134 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SEARCH_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function search
+///
+/// range-based version of the search std algorithm
+///
+/// \pre ForwardRange1 is a model of the ForwardRangeConcept
+/// \pre ForwardRange2 is a model of the ForwardRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return std::search(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2));
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange1>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred);
+}
+
+/// \overload
+template< class ForwardRange1, class ForwardRange2, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange1>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return std::search(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return range_return<ForwardRange1,re>::
+ pack(std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2 >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return range_return<const ForwardRange1,re>::
+ pack(std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2)),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange1,re>::type
+search(ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return range_return<ForwardRange1,re>::
+ pack(std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred),
+ rng1);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange1, class ForwardRange2,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange1,re>::type
+search(const ForwardRange1& rng1, const ForwardRange2& rng2, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange2> ));
+ return range_return<const ForwardRange1,re>::
+ pack(std::search(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2),pred),
+ rng1);
+}
+
+ } // namespace range
+ using range::search;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/search_n.hpp b/src/boost/range/algorithm/search_n.hpp
new file mode 100644
index 0000000..ca2b6ef
--- /dev/null
+++ b/src/boost/range/algorithm/search_n.hpp
@@ -0,0 +1,360 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SEARCH_N_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <boost/range/value_type.hpp>
+#include <iterator>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+namespace range_detail
+{
+ // Rationale: search_n is implemented rather than delegate to
+ // the standard library implementation because some standard
+ // library implementations are broken eg. MSVC.
+
+ // search_n forward iterator version
+ template<typename ForwardIterator, typename Integer, typename Value>
+ inline ForwardIterator
+ search_n_impl(ForwardIterator first, ForwardIterator last, Integer count,
+ const Value& value, std::forward_iterator_tag)
+ {
+ first = std::find(first, last, value);
+ while (first != last)
+ {
+ typename std::iterator_traits<ForwardIterator>::difference_type n = count;
+ ForwardIterator i = first;
+ ++i;
+ while (i != last && n != 1 && *i==value)
+ {
+ ++i;
+ --n;
+ }
+ if (n == 1)
+ return first;
+ if (i == last)
+ return last;
+ first = std::find(++i, last, value);
+ }
+ return last;
+ }
+
+ // search_n random-access iterator version
+ template<typename RandomAccessIterator, typename Integer, typename Value>
+ inline RandomAccessIterator
+ search_n_impl(RandomAccessIterator first, RandomAccessIterator last,
+ Integer count, const Value& value,
+ std::random_access_iterator_tag)
+ {
+ typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
+
+ difference_t tail_size = last - first;
+ const difference_t pattern_size = count;
+
+ if (tail_size < pattern_size)
+ return last;
+
+ const difference_t skip_offset = pattern_size - 1;
+ RandomAccessIterator look_ahead = first + skip_offset;
+ tail_size -= pattern_size;
+
+ while (1)
+ {
+ // look_ahead here is pointing to the last element of the
+ // next possible match
+ while (!(*look_ahead == value)) // skip loop...
+ {
+ if (tail_size < pattern_size)
+ return last; // no match
+ look_ahead += pattern_size;
+ tail_size -= pattern_size;
+ }
+ difference_t remainder = skip_offset;
+ for (RandomAccessIterator back_track = look_ahead - 1;
+ *back_track == value; --back_track)
+ {
+ if (--remainder == 0)
+ {
+ return look_ahead - skip_offset; // matched
+ }
+ }
+ if (remainder > tail_size)
+ return last; // no match
+ look_ahead += remainder;
+ tail_size -= remainder;
+ }
+
+ return last;
+ }
+
+ // search_n for forward iterators using a binary predicate
+ // to determine a match
+ template<typename ForwardIterator, typename Integer, typename Value,
+ typename BinaryPredicate>
+ inline ForwardIterator
+ search_n_pred_impl(ForwardIterator first, ForwardIterator last,
+ Integer count, const Value& value,
+ BinaryPredicate pred, std::forward_iterator_tag)
+ {
+ typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_t;
+
+ while (first != last && !static_cast<bool>(pred(*first, value)))
+ ++first;
+
+ while (first != last)
+ {
+ difference_t n = count;
+ ForwardIterator i = first;
+ ++i;
+ while (i != last && n != 1 && static_cast<bool>(pred(*i, value)))
+ {
+ ++i;
+ --n;
+ }
+ if (n == 1)
+ return first;
+ if (i == last)
+ return last;
+ first = ++i;
+ while (first != last && !static_cast<bool>(pred(*first, value)))
+ ++first;
+ }
+ return last;
+ }
+
+ // search_n for random-access iterators using a binary predicate
+ // to determine a match
+ template<typename RandomAccessIterator, typename Integer,
+ typename Value, typename BinaryPredicate>
+ inline RandomAccessIterator
+ search_n_pred_impl(RandomAccessIterator first, RandomAccessIterator last,
+ Integer count, const Value& value,
+ BinaryPredicate pred, std::random_access_iterator_tag)
+ {
+ typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_t;
+
+ difference_t tail_size = last - first;
+ const difference_t pattern_size = count;
+
+ if (tail_size < pattern_size)
+ return last;
+
+ const difference_t skip_offset = pattern_size - 1;
+ RandomAccessIterator look_ahead = first + skip_offset;
+ tail_size -= pattern_size;
+
+ while (1)
+ {
+ // look_ahead points to the last element of the next
+ // possible match
+ while (!static_cast<bool>(pred(*look_ahead, value))) // skip loop
+ {
+ if (tail_size < pattern_size)
+ return last; // no match
+ look_ahead += pattern_size;
+ tail_size -= pattern_size;
+ }
+ difference_t remainder = skip_offset;
+ for (RandomAccessIterator back_track = look_ahead - 1;
+ pred(*back_track, value); --back_track)
+ {
+ if (--remainder == 0)
+ return look_ahead -= skip_offset; // success
+ }
+ if (remainder > tail_size)
+ {
+ return last; // no match
+ }
+ look_ahead += remainder;
+ tail_size -= remainder;
+ }
+ }
+
+ template<typename ForwardIterator, typename Integer, typename Value>
+ inline ForwardIterator
+ search_n_impl(ForwardIterator first, ForwardIterator last,
+ Integer count, const Value& value)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
+ BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<Value>));
+ BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept<typename std::iterator_traits<ForwardIterator>::value_type>));
+ //BOOST_RANGE_CONCEPT_ASSERT((EqualityComparableConcept2<typename std::iterator_traits<ForwardIterator>::value_type, Value>));
+
+ typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
+
+ if (count <= 0)
+ return first;
+ if (count == 1)
+ return std::find(first, last, value);
+ return range_detail::search_n_impl(first, last, count, value, cat_t());
+ }
+
+ template<typename ForwardIterator, typename Integer, typename Value,
+ typename BinaryPredicate>
+ inline ForwardIterator
+ search_n_pred_impl(ForwardIterator first, ForwardIterator last,
+ Integer count, const Value& value,
+ BinaryPredicate pred)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardIteratorConcept<ForwardIterator>));
+ BOOST_RANGE_CONCEPT_ASSERT((
+ BinaryPredicateConcept<
+ BinaryPredicate,
+ typename std::iterator_traits<ForwardIterator>::value_type,
+ Value>
+ ));
+
+ typedef typename std::iterator_traits<ForwardIterator>::iterator_category cat_t;
+
+ if (count <= 0)
+ return first;
+ if (count == 1)
+ {
+ while (first != last && !static_cast<bool>(pred(*first, value)))
+ ++first;
+ return first;
+ }
+ return range_detail::search_n_pred_impl(first, last, count,
+ value, pred, cat_t());
+ }
+} // namespace range_detail
+
+/// \brief template function search
+///
+/// range-based version of the search std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+/// \pre Integer is an integral type
+/// \pre Value is a model of the EqualityComparableConcept
+/// \pre ForwardRange's value type is a model of the EqualityComparableConcept
+/// \pre Object's of ForwardRange's value type can be compared for equality with Objects of type Value
+template< class ForwardRange, class Integer, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+search_n(ForwardRange& rng, Integer count, const Value& value)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_detail::search_n_impl(boost::begin(rng),boost::end(rng), count, value);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+ return range_detail::search_n_impl(boost::begin(rng), boost::end(rng), count, value);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+search_n(ForwardRange& rng, Integer count, const Value& value,
+ BinaryPredicate binary_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type, const Value&>));
+ return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
+ count, value, binary_pred);
+}
+
+/// \overload
+template< class ForwardRange, class Integer, class Value,
+ class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value,
+ BinaryPredicate binary_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type, const Value&>));
+ return range_detail::search_n_pred_impl(boost::begin(rng), boost::end(rng),
+ count, value, binary_pred);
+}
+
+// range_return overloads
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+ class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+search_n(ForwardRange& rng, Integer count, const Value& value)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ return range_return<ForwardRange,re>::
+ pack(range_detail::search_n_impl(boost::begin(rng),boost::end(rng),
+ count, value),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+ class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+ return range_return<const ForwardRange,re>::
+ pack(range_detail::search_n_impl(boost::begin(rng), boost::end(rng),
+ count, value),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+ class Value, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+search_n(ForwardRange& rng, Integer count, const Value& value,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type,
+ const Value&>));
+ return range_return<ForwardRange,re>::
+ pack(range_detail::search_n_pred_impl(boost::begin(rng),
+ boost::end(rng),
+ count, value, pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Integer,
+ class Value, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+search_n(const ForwardRange& rng, Integer count, const Value& value,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<const ForwardRange>::type,
+ const Value&>));
+ return range_return<const ForwardRange,re>::
+ pack(range_detail::search_n_pred_impl(boost::begin(rng),
+ boost::end(rng),
+ count, value, pred),
+ rng);
+}
+
+ } // namespace range
+ using range::search_n;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/set_algorithm.hpp b/src/boost/range/algorithm/set_algorithm.hpp
new file mode 100644
index 0000000..82ef8ec
--- /dev/null
+++ b/src/boost/range/algorithm/set_algorithm.hpp
@@ -0,0 +1,198 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SET_ALGORITHM_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function includes
+///
+/// range-based version of the includes std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2>
+inline bool includes(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::includes(boost::begin(rng1),boost::end(rng1),
+ boost::begin(rng2),boost::end(rng2));
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class BinaryPredicate>
+inline bool includes(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::includes(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), pred);
+}
+
+/// \brief template function set_union
+///
+/// range-based version of the set_union std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator set_union(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_union(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_union(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_union(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+/// \brief template function set_intersection
+///
+/// range-based version of the set_intersection std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator set_intersection(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_intersection(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_intersection(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_intersection(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2),
+ out, pred);
+}
+
+/// \brief template function set_difference
+///
+/// range-based version of the set_difference std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator set_difference(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_difference(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator set_difference(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_difference(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+/// \brief template function set_symmetric_difference
+///
+/// range-based version of the set_symmetric_difference std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator>
+inline OutputIterator
+set_symmetric_difference(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_symmetric_difference(boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out);
+}
+
+/// \overload
+template<class SinglePassRange1, class SinglePassRange2,
+ class OutputIterator, class BinaryPredicate>
+inline OutputIterator
+set_symmetric_difference(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return std::set_symmetric_difference(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2), out, pred);
+}
+
+ } // namespace range
+ using range::includes;
+ using range::set_union;
+ using range::set_intersection;
+ using range::set_difference;
+ using range::set_symmetric_difference;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/sort.hpp b/src/boost/range/algorithm/sort.hpp
new file mode 100644
index 0000000..45eecde
--- /dev/null
+++ b/src/boost/range/algorithm/sort.hpp
@@ -0,0 +1,68 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function sort
+///
+/// range-based version of the sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& sort(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::sort(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& sort(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::sort(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::sort(boost::begin(rng), boost::end(rng), pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::sort(boost::begin(rng), boost::end(rng), pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/stable_partition.hpp b/src/boost/range/algorithm/stable_partition.hpp
new file mode 100644
index 0000000..24febfc
--- /dev/null
+++ b/src/boost/range/algorithm/stable_partition.hpp
@@ -0,0 +1,73 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_STABLE_PARTITION_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function stable_partition
+///
+/// range-based version of the stable_partition std algorithm
+///
+/// \pre BidirectionalRange is a model of the BidirectionalRangeConcept
+/// \pre UnaryPredicate is a model of the UnaryPredicateConcept
+template<class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type
+stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return std::stable_partition(boost::begin(rng), boost::end(rng), pred);
+}
+
+/// \overload
+template<class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_iterator<const BidirectionalRange>::type
+stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return std::stable_partition(boost::begin(rng),boost::end(rng),pred);
+}
+
+// range_return overloads
+template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<BidirectionalRange,re>::type
+stable_partition(BidirectionalRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<BidirectionalRange> ));
+ return range_return<BidirectionalRange,re>::pack(
+ std::stable_partition(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template<range_return_value re, class BidirectionalRange, class UnaryPredicate>
+inline BOOST_DEDUCED_TYPENAME range_return<const BidirectionalRange,re>::type
+stable_partition(const BidirectionalRange& rng, UnaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalRangeConcept<const BidirectionalRange> ));
+ return range_return<const BidirectionalRange,re>::pack(
+ std::stable_partition(boost::begin(rng),boost::end(rng),pred),
+ rng);
+}
+
+ } // namespace range
+ using range::stable_partition;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/stable_sort.hpp b/src/boost/range/algorithm/stable_sort.hpp
new file mode 100644
index 0000000..d18da4d
--- /dev/null
+++ b/src/boost/range/algorithm/stable_sort.hpp
@@ -0,0 +1,68 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_STABLE_SORT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function stable_sort
+///
+/// range-based version of the stable_sort std algorithm
+///
+/// \pre RandomAccessRange is a model of the RandomAccessRangeConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template<class RandomAccessRange>
+inline RandomAccessRange& stable_sort(RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::stable_sort(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange>
+inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::stable_sort(boost::begin(rng), boost::end(rng));
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline RandomAccessRange& stable_sort(RandomAccessRange& rng, BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
+ std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
+ return rng;
+}
+
+/// \overload
+template<class RandomAccessRange, class BinaryPredicate>
+inline const RandomAccessRange& stable_sort(const RandomAccessRange& rng, BinaryPredicate sort_pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
+ std::stable_sort(boost::begin(rng), boost::end(rng), sort_pred);
+ return rng;
+}
+
+ } // namespace range
+ using range::stable_sort;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/swap_ranges.hpp b/src/boost/range/algorithm/swap_ranges.hpp
new file mode 100644
index 0000000..52b0162
--- /dev/null
+++ b/src/boost/range/algorithm/swap_ranges.hpp
@@ -0,0 +1,132 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template<class Iterator1, class Iterator2>
+ void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
+ Iterator2 it2, Iterator2 last2,
+ single_pass_traversal_tag,
+ single_pass_traversal_tag)
+ {
+ ignore_unused_variable_warning(last2);
+ for (; it1 != last1; ++it1, ++it2)
+ {
+ BOOST_ASSERT( it2 != last2 );
+ std::iter_swap(it1, it2);
+ }
+ }
+
+ template<class Iterator1, class Iterator2>
+ void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
+ Iterator2 it2, Iterator2 last2,
+ random_access_traversal_tag,
+ random_access_traversal_tag)
+ {
+ ignore_unused_variable_warning(last2);
+ BOOST_ASSERT( last2 - it2 >= last1 - it1 );
+ std::swap_ranges(it1, last1, it2);
+ }
+
+ template<class Iterator1, class Iterator2>
+ void swap_ranges_impl(Iterator1 first1, Iterator1 last1,
+ Iterator2 first2, Iterator2 last2)
+ {
+ swap_ranges_impl(first1, last1, first2, last2,
+ BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator1>::type(),
+ BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator2>::type());
+ }
+ } // namespace range_detail
+
+ namespace range
+ {
+
+/// \brief template function swap_ranges
+///
+/// range-based version of the swap_ranges std algorithm
+///
+/// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+/// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+template< class SinglePassRange1, class SinglePassRange2 >
+inline SinglePassRange2&
+swap_ranges(SinglePassRange1& range1, SinglePassRange2& range2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
+
+ boost::range_detail::swap_ranges_impl(
+ boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+
+ return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline SinglePassRange2&
+swap_ranges(const SinglePassRange1& range1, SinglePassRange2& range2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
+
+ boost::range_detail::swap_ranges_impl(
+ boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+
+ return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline const SinglePassRange2&
+swap_ranges(SinglePassRange1& range1, const SinglePassRange2& range2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
+
+ boost::range_detail::swap_ranges_impl(
+ boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+
+ return range2;
+}
+
+/// \overload
+template< class SinglePassRange1, class SinglePassRange2 >
+inline const SinglePassRange2&
+swap_ranges(const SinglePassRange1& range1, const SinglePassRange2& range2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
+
+ boost::range_detail::swap_ranges_impl(
+ boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+
+ return range2;
+}
+
+ } // namespace range
+ using range::swap_ranges;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/transform.hpp b/src/boost/range/algorithm/transform.hpp
new file mode 100644
index 0000000..fb03441
--- /dev/null
+++ b/src/boost/range/algorithm/transform.hpp
@@ -0,0 +1,97 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_TRANSFORM_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+ /// \brief template function transform
+ ///
+ /// range-based version of the transform std algorithm
+ ///
+ /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
+ /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
+ /// \pre OutputIterator is a model of the OutputIteratorConcept
+ /// \pre UnaryOperation is a model of the UnaryFunctionConcept
+ /// \pre BinaryOperation is a model of the BinaryFunctionConcept
+ template< class SinglePassRange1,
+ class OutputIterator,
+ class UnaryOperation >
+ inline OutputIterator
+ transform(const SinglePassRange1& rng,
+ OutputIterator out,
+ UnaryOperation fun)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ return std::transform(boost::begin(rng),boost::end(rng),out,fun);
+ }
+
+ } // namespace range
+
+ namespace range_detail
+ {
+ template< class SinglePassTraversalReadableIterator1,
+ class SinglePassTraversalReadableIterator2,
+ class OutputIterator,
+ class BinaryFunction >
+ inline OutputIterator
+ transform_impl(SinglePassTraversalReadableIterator1 first1,
+ SinglePassTraversalReadableIterator1 last1,
+ SinglePassTraversalReadableIterator2 first2,
+ SinglePassTraversalReadableIterator2 last2,
+ OutputIterator out,
+ BinaryFunction fn)
+ {
+ for (; first1 != last1; ++first1, ++first2)
+ {
+ BOOST_ASSERT( first2 != last2 );
+ *out = fn(*first1, *first2);
+ ++out;
+ }
+ return out;
+ }
+ }
+
+ namespace range
+ {
+
+ /// \overload
+ template< class SinglePassRange1,
+ class SinglePassRange2,
+ class OutputIterator,
+ class BinaryOperation >
+ inline OutputIterator
+ transform(const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ OutputIterator out,
+ BinaryOperation fun)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ return boost::range_detail::transform_impl(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), boost::end(rng2),
+ out, fun);
+ }
+
+ } // namespace range
+ using range::transform;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/unique.hpp b/src/boost/range/algorithm/unique.hpp
new file mode 100644
index 0000000..be6eaf9
--- /dev/null
+++ b/src/boost/range/algorithm/unique.hpp
@@ -0,0 +1,107 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UNIQUE_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function unique
+///
+/// range-based version of the unique std algorithm
+///
+/// \pre Rng meets the requirements for a Forward range
+template< range_return_value re, class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+unique( ForwardRange& rng )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack( std::unique( boost::begin(rng),
+ boost::end(rng)), rng );
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+unique( const ForwardRange& rng )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack( std::unique( boost::begin(rng),
+ boost::end(rng)), rng );
+}
+/// \overload
+template< range_return_value re, class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+unique( ForwardRange& rng, BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::unique(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+/// \overload
+template< range_return_value re, class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+unique( const ForwardRange& rng, BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::unique(boost::begin(rng), boost::end(rng), pred),
+ rng);
+}
+
+/// \overload
+template< class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
+unique( ForwardRange& rng )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return ::boost::range::unique<return_begin_found>(rng);
+}
+/// \overload
+template< class ForwardRange >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
+unique( const ForwardRange& rng )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return ::boost::range::unique<return_begin_found>(rng);
+}
+/// \overload
+template< class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
+unique( ForwardRange& rng, BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return ::boost::range::unique<return_begin_found>(rng);
+}
+/// \overload
+template< class ForwardRange, class BinaryPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+unique( const ForwardRange& rng, BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return ::boost::range::unique<return_begin_found>(rng, pred);
+}
+
+ } // namespace range
+ using range::unique;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/unique_copy.hpp b/src/boost/range/algorithm/unique_copy.hpp
new file mode 100644
index 0000000..0682d74
--- /dev/null
+++ b/src/boost/range/algorithm/unique_copy.hpp
@@ -0,0 +1,51 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UNIQUE_COPY_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function unique_copy
+///
+/// range-based version of the unique_copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+/// \pre BinaryPredicate is a model of the BinaryPredicateConcept
+template< class SinglePassRange, class OutputIterator >
+inline OutputIterator
+unique_copy( const SinglePassRange& rng, OutputIterator out_it )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::unique_copy(boost::begin(rng), boost::end(rng), out_it);
+}
+/// \overload
+template< class SinglePassRange, class OutputIterator, class BinaryPredicate >
+inline OutputIterator
+unique_copy( const SinglePassRange& rng, OutputIterator out_it,
+ BinaryPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::unique_copy(boost::begin(rng), boost::end(rng), out_it, pred);
+}
+
+ } // namespace range
+ using range::unique_copy;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm/upper_bound.hpp b/src/boost/range/algorithm/upper_bound.hpp
new file mode 100644
index 0000000..c8acbc6
--- /dev/null
+++ b/src/boost/range/algorithm/upper_bound.hpp
@@ -0,0 +1,127 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_UPPER_BOUND_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/detail/range_return.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function upper_bound
+///
+/// range-based version of the upper_bound std algorithm
+///
+/// \pre ForwardRange is a model of the ForwardRangeConcept
+template< class ForwardRange, class Value >
+inline
+BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+upper_bound( ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::upper_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value >
+BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+upper_bound( const ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::upper_bound(boost::begin(rng), boost::end(rng), val);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
+>::type
+upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< class ForwardRange, class Value, class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
+upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return std::upper_bound(boost::begin(rng), boost::end(rng), val, pred);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+upper_bound( ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+upper_bound( const ForwardRange& rng, Value val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::upper_bound(boost::begin(rng), boost::end(rng), val),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value,
+ class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME disable_if<
+ is_const<ForwardRange>,
+ BOOST_DEDUCED_TYPENAME range_return<ForwardRange,re>::type
+>::type
+upper_bound( ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ return range_return<ForwardRange,re>::
+ pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
+ rng);
+}
+
+/// \overload
+template< range_return_value re, class ForwardRange, class Value,
+ class SortPredicate >
+inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange,re>::type
+upper_bound( const ForwardRange& rng, Value val, SortPredicate pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ return range_return<const ForwardRange,re>::
+ pack(std::upper_bound(boost::begin(rng), boost::end(rng), val, pred),
+ rng);
+}
+
+ } // namespace range
+ using range::upper_bound;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext.hpp b/src/boost/range/algorithm_ext.hpp
new file mode 100644
index 0000000..783d38a
--- /dev/null
+++ b/src/boost/range/algorithm_ext.hpp
@@ -0,0 +1,28 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Copyright Thorsten Ottosen 2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_HPP
+#define BOOST_RANGE_ALGORITHM_EXT_HPP
+
+#include <boost/range/algorithm_ext/copy_n.hpp>
+#include <boost/range/algorithm_ext/for_each.hpp>
+#include <boost/range/algorithm_ext/is_sorted.hpp>
+#include <boost/range/algorithm_ext/iota.hpp>
+#include <boost/range/algorithm_ext/overwrite.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+#include <boost/range/algorithm_ext/push_front.hpp>
+#include <boost/range/algorithm_ext/insert.hpp>
+#include <boost/range/algorithm_ext/erase.hpp>
+
+#endif
diff --git a/src/boost/range/algorithm_ext/copy_n.hpp b/src/boost/range/algorithm_ext/copy_n.hpp
new file mode 100644
index 0000000..f855441
--- /dev/null
+++ b/src/boost/range/algorithm_ext/copy_n.hpp
@@ -0,0 +1,53 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_COPY_N_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_COPY_N_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function copy
+///
+/// range-based version of the copy std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+/// \pre OutputIterator is a model of the OutputIteratorConcept
+/// \pre 0 <= n <= distance(rng)
+template< class SinglePassRange, class Size, class OutputIterator >
+inline OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator out)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ BOOST_ASSERT( n <= static_cast<Size>(::boost::distance(rng)) );
+ BOOST_ASSERT( n >= static_cast<Size>(0) );
+
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type source = ::boost::begin(rng);
+
+ for (Size i = 0; i < n; ++i, ++out, ++source)
+ *out = *source;
+
+ return out;
+}
+
+ } // namespace range
+ using ::boost::range::copy_n;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext/erase.hpp b/src/boost/range/algorithm_ext/erase.hpp
new file mode 100644
index 0000000..107d32b
--- /dev/null
+++ b/src/boost/range/algorithm_ext/erase.hpp
@@ -0,0 +1,61 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_ERASE_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+
+template< class Container >
+inline Container& erase( Container& on,
+ iterator_range<BOOST_DEDUCED_TYPENAME Container::iterator> to_erase )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+ on.erase( boost::begin(to_erase), boost::end(to_erase) );
+ return on;
+}
+
+template< class Container, class T >
+inline Container& remove_erase( Container& on, const T& val )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+ on.erase(
+ std::remove(boost::begin(on), boost::end(on), val),
+ boost::end(on));
+ return on;
+}
+
+template< class Container, class Pred >
+inline Container& remove_erase_if( Container& on, Pred pred )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+ on.erase(
+ std::remove_if(boost::begin(on), boost::end(on), pred),
+ boost::end(on));
+ return on;
+}
+
+ } // namespace range
+ using range::erase;
+ using range::remove_erase;
+ using range::remove_erase_if;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext/for_each.hpp b/src/boost/range/algorithm_ext/for_each.hpp
new file mode 100644
index 0000000..a470e2b
--- /dev/null
+++ b/src/boost/range/algorithm_ext/for_each.hpp
@@ -0,0 +1,86 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_FOR_EACH_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template<class InputIterator1, class InputIterator2, class Fn2>
+ inline Fn2 for_each_impl(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ Fn2 fn)
+ {
+ for (; first1 != last1 && first2 != last2; ++first1, ++first2)
+ {
+ fn(*first1, *first2);
+ }
+ return fn;
+ }
+ }
+
+ namespace range
+ {
+ template<class SinglePassRange1, class SinglePassRange2, class Fn2>
+ inline Fn2 for_each(const SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::for_each_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), fn);
+ }
+
+ template<class SinglePassRange1, class SinglePassRange2, class Fn2>
+ inline Fn2 for_each(const SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::for_each_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), fn);
+ }
+
+ template<class SinglePassRange1, class SinglePassRange2, class Fn2>
+ inline Fn2 for_each(SinglePassRange1& rng1, const SinglePassRange2& rng2, Fn2 fn)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ return ::boost::range_detail::for_each_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), fn);
+ }
+
+ template<class SinglePassRange1, class SinglePassRange2, class Fn2>
+ inline Fn2 for_each(SinglePassRange1& rng1, SinglePassRange2& rng2, Fn2 fn)
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return ::boost::range_detail::for_each_impl(
+ ::boost::begin(rng1), ::boost::end(rng1),
+ ::boost::begin(rng2), ::boost::end(rng2), fn);
+ }
+ } // namespace range
+ using range::for_each;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext/insert.hpp b/src/boost/range/algorithm_ext/insert.hpp
new file mode 100644
index 0000000..b9adfdd
--- /dev/null
+++ b/src/boost/range/algorithm_ext/insert.hpp
@@ -0,0 +1,42 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_INSERT_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+
+template< class Container, class Range >
+inline Container& insert( Container& on,
+ BOOST_DEDUCED_TYPENAME Container::iterator before,
+ const Range& from )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Range> ));
+ BOOST_ASSERT( (void*)&on != (void*)&from &&
+ "cannot copy from a container to itself" );
+ on.insert( before, boost::begin(from), boost::end(from) );
+ return on;
+}
+
+ } // namespace range
+ using range::insert;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext/iota.hpp b/src/boost/range/algorithm_ext/iota.hpp
new file mode 100644
index 0000000..f7af446
--- /dev/null
+++ b/src/boost/range/algorithm_ext/iota.hpp
@@ -0,0 +1,54 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_IOTA_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+
+template< class ForwardRange, class Value >
+inline ForwardRange& iota( ForwardRange& rng, Value x )
+{
+ BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
+
+ iterator_t last_target = ::boost::end(rng);
+ for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x)
+ *target = x;
+
+ return rng;
+}
+
+template< class ForwardRange, class Value >
+inline const ForwardRange& iota( const ForwardRange& rng, Value x )
+{
+ BOOST_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type iterator_t;
+
+ iterator_t last_target = ::boost::end(rng);
+ for (iterator_t target = ::boost::begin(rng); target != last_target; ++target, ++x)
+ *target = x;
+
+ return rng;
+}
+
+ } // namespace range
+ using range::iota;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext/is_sorted.hpp b/src/boost/range/algorithm_ext/is_sorted.hpp
new file mode 100644
index 0000000..3d00729
--- /dev/null
+++ b/src/boost/range/algorithm_ext/is_sorted.hpp
@@ -0,0 +1,57 @@
+// Copyright Bryce Lelbach 2010
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_IS_SORTED_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/detail/is_sorted.hpp>
+#include <algorithm>
+
+namespace boost
+{
+ namespace range
+ {
+
+/// \brief template function is_sorted
+///
+/// range-based version of the is_sorted std algorithm
+///
+/// \pre SinglePassRange is a model of the SinglePassRangeConcept
+template<class SinglePassRange>
+inline bool is_sorted(const SinglePassRange& rng)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept<BOOST_DEDUCED_TYPENAME
+ range_value<const SinglePassRange>::type>));
+ return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng));
+}
+
+/// \overload
+template<class SinglePassRange, class BinaryPredicate>
+inline bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred)
+{
+ BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange>));
+ BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept<BinaryPredicate,
+ BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type,
+ BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type>));
+ return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng), pred);
+}
+
+ } // namespace range
+
+using range::is_sorted;
+
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext/overwrite.hpp b/src/boost/range/algorithm_ext/overwrite.hpp
new file mode 100644
index 0000000..f84f6ea
--- /dev/null
+++ b/src/boost/range/algorithm_ext/overwrite.hpp
@@ -0,0 +1,84 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_OVERWRITE_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+
+template< class SinglePassRange1, class SinglePassRange2 >
+inline void overwrite( const SinglePassRange1& from, SinglePassRange2& to )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+ i = boost::begin(from), e = boost::end(from);
+
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type
+ out = boost::begin(to);
+
+#ifndef NDEBUG
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type
+ last_out = boost::end(to);
+#endif
+
+ for( ; i != e; ++out, ++i )
+ {
+#ifndef NDEBUG
+ BOOST_ASSERT( out != last_out
+ && "out of bounds in boost::overwrite()" );
+#endif
+ *out = *i;
+ }
+}
+
+template< class SinglePassRange1, class SinglePassRange2 >
+inline void overwrite( const SinglePassRange1& from, const SinglePassRange2& to )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type
+ i = boost::begin(from), e = boost::end(from);
+
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type
+ out = boost::begin(to);
+
+#ifndef NDEBUG
+ BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type
+ last_out = boost::end(to);
+#endif
+
+ for( ; i != e; ++out, ++i )
+ {
+#ifndef NDEBUG
+ BOOST_ASSERT( out != last_out
+ && "out of bounds in boost::overwrite()" );
+#endif
+ *out = *i;
+ }
+}
+
+ } // namespace range
+ using range::overwrite;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext/push_back.hpp b/src/boost/range/algorithm_ext/push_back.hpp
new file mode 100644
index 0000000..51a7a7b
--- /dev/null
+++ b/src/boost/range/algorithm_ext/push_back.hpp
@@ -0,0 +1,40 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_PUSH_BACK_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+
+template< class Container, class Range >
+inline Container& push_back( Container& on, const Range& from )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Container> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const Range> ));
+ BOOST_ASSERT( (void*)&on != (void*)&from &&
+ "cannot copy from a container to itself" );
+ on.insert( on.end(), boost::begin(from), boost::end(from) );
+ return on;
+}
+
+ } // namespace range
+ using range::push_back;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/algorithm_ext/push_front.hpp b/src/boost/range/algorithm_ext/push_front.hpp
new file mode 100644
index 0000000..470d793
--- /dev/null
+++ b/src/boost/range/algorithm_ext/push_front.hpp
@@ -0,0 +1,40 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED
+#define BOOST_RANGE_ALGORITHM_EXT_PUSH_FRONT_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+
+template< class Container, class Range >
+inline Container& push_front( Container& on, const Range& from )
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Container> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const Range> ));
+ BOOST_ASSERT( (void*)&on != (void*)&from &&
+ "cannot copy from a container to itself" );
+ on.insert( on.begin(), boost::begin(from), boost::end(from) );
+ return on;
+}
+
+ } // namespace range
+ using range::push_front;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/any_range.hpp b/src/boost/range/any_range.hpp
new file mode 100644
index 0000000..ba4c224
--- /dev/null
+++ b/src/boost/range/any_range.hpp
@@ -0,0 +1,205 @@
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ANY_RANGE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/range/detail/any_iterator.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/reference.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/cast.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ // If T is use_default, return the result of Default, otherwise
+ // return T.
+ //
+ // This is an implementation artifact used to pick intelligent default
+ // values when the user specified boost::use_default as a template
+ // parameter.
+ template<
+ class T,
+ class Default
+ >
+ struct any_range_default_help
+ : mpl::eval_if<
+ is_same<T, use_default>
+ , Default
+ , mpl::identity<T>
+ >
+ {
+ };
+
+ template<
+ class WrappedRange
+ , class Value
+ , class Reference
+ >
+ struct any_range_value_type
+ {
+# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
+ typedef typename any_range_default_help<
+ Value
+ , mpl::eval_if<
+ is_same<Reference, use_default>
+ , range_value<
+ typename remove_const<WrappedRange>
+ ::type>
+ , remove_reference<Reference>
+ >
+ >::type type;
+# else
+ typedef typename any_range_default_help<
+ Value
+ , range_value<
+ typename remove_const<WrappedRange>
+ ::type>
+ >::type type;
+# endif
+ };
+
+ template<
+ class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer = use_default
+ >
+ class any_range
+ : public iterator_range<
+ any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , typename any_range_default_help<
+ Buffer
+ , mpl::identity<any_iterator_default_buffer>
+ >::type
+ >
+ >
+ {
+ typedef iterator_range<
+ any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , typename any_range_default_help<
+ Buffer
+ , mpl::identity<any_iterator_default_buffer>
+ >::type
+ >
+ > base_type;
+
+ struct enabler {};
+ struct disabler {};
+ public:
+ any_range()
+ {
+ }
+
+ any_range(const any_range& other)
+ : base_type(other)
+ {
+ }
+
+ template<class WrappedRange>
+ any_range(WrappedRange& wrapped_range)
+ : base_type(boost::begin(wrapped_range),
+ boost::end(wrapped_range))
+ {
+ }
+
+ template<class WrappedRange>
+ any_range(const WrappedRange& wrapped_range)
+ : base_type(boost::begin(wrapped_range),
+ boost::end(wrapped_range))
+ {
+ }
+
+ template<
+ class OtherValue
+ , class OtherTraversal
+ , class OtherReference
+ , class OtherDifference
+ >
+ any_range(const any_range<
+ OtherValue
+ , OtherTraversal
+ , OtherReference
+ , OtherDifference
+ , Buffer
+ >& other)
+ : base_type(boost::begin(other), boost::end(other))
+ {
+ }
+
+ template<class Iterator>
+ any_range(Iterator first, Iterator last)
+ : base_type(first, last)
+ {
+ }
+ };
+
+ template<
+ class WrappedRange
+ , class Value = use_default
+ , class Traversal = use_default
+ , class Reference = use_default
+ , class Difference = use_default
+ , class Buffer = use_default
+ >
+ struct any_range_type_generator
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<WrappedRange> ));
+ typedef any_range<
+ typename any_range_value_type<
+ WrappedRange
+ , Value
+ , typename any_range_default_help<
+ Reference
+ , range_reference<WrappedRange>
+ >::type
+ >::type
+ , typename any_range_default_help<
+ Traversal
+ , iterator_traversal<
+ typename range_iterator<WrappedRange>::type
+ >
+ >::type
+ , typename any_range_default_help<
+ Reference
+ , range_reference<WrappedRange>
+ >::type
+ , typename any_range_default_help<
+ Difference
+ , range_difference<WrappedRange>
+ >::type
+ , typename any_range_default_help<
+ Buffer
+ , mpl::identity<any_iterator_default_buffer>
+ >::type
+ > type;
+ };
+ } // namespace range_detail
+
+ using range_detail::any_range;
+ using range_detail::any_range_type_generator;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/as_array.hpp b/src/boost/range/as_array.hpp
new file mode 100644
index 0000000..0723e60
--- /dev/null
+++ b/src/boost/range/as_array.hpp
@@ -0,0 +1,45 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_AS_ARRAY_HPP
+#define BOOST_RANGE_AS_ARRAY_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/detail/str_types.hpp>
+
+namespace boost
+{
+
+ template< class R >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<R>::type >
+ as_array( R& r )
+ {
+ return boost::make_iterator_range( r );
+ }
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< class Range >
+ inline boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type >
+ as_array( const Range& r )
+ {
+ return boost::make_iterator_range( r );
+ }
+
+#endif
+
+}
+
+#endif
+
diff --git a/src/boost/range/as_literal.hpp b/src/boost/range/as_literal.hpp
new file mode 100644
index 0000000..9ea144d
--- /dev/null
+++ b/src/boost/range/as_literal.hpp
@@ -0,0 +1,127 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_AS_LITERAL_HPP
+#define BOOST_RANGE_AS_LITERAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+#include <boost/range/detail/as_literal.hpp>
+#else
+
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/detail/str_types.hpp>
+
+#include <boost/detail/workaround.hpp>
+
+#include <cstring>
+#ifndef BOOST_NO_CWCHAR
+#include <cwchar>
+#endif
+
+namespace boost
+{
+ namespace range_detail
+ {
+ inline std::size_t length( const char* s )
+ {
+ return strlen( s );
+ }
+
+#ifndef BOOST_NO_CWCHAR
+ inline std::size_t length( const wchar_t* s )
+ {
+ return wcslen( s );
+ }
+#endif
+
+ //
+ // Remark: the compiler cannot choose between T* and T[sz]
+ // overloads, so we must put the T* internal to the
+ // unconstrained version.
+ //
+
+ inline bool is_char_ptr( char* )
+ {
+ return true;
+ }
+
+ inline bool is_char_ptr( const char* )
+ {
+ return true;
+ }
+
+#ifndef BOOST_NO_CWCHAR
+ inline bool is_char_ptr( wchar_t* )
+ {
+ return true;
+ }
+
+ inline bool is_char_ptr( const wchar_t* )
+ {
+ return true;
+ }
+#endif
+
+ template< class T >
+ inline long is_char_ptr( const T& /* r */ )
+ {
+ return 0L;
+ }
+
+ template< class T >
+ inline iterator_range<T*>
+ make_range( T* const r, bool )
+ {
+ return iterator_range<T*>( r, r + length(r) );
+ }
+
+ template< class T >
+ inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<T>::type>
+ make_range( T& r, long )
+ {
+ return boost::make_iterator_range( r );
+ }
+
+ }
+
+ template< class Range >
+ inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type>
+ as_literal( Range& r )
+ {
+ return range_detail::make_range( r, range_detail::is_char_ptr(r) );
+ }
+
+ template< class Range >
+ inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type>
+ as_literal( const Range& r )
+ {
+ return range_detail::make_range( r, range_detail::is_char_ptr(r) );
+ }
+
+ template< class Char, std::size_t sz >
+ inline iterator_range<Char*> as_literal( Char (&arr)[sz] )
+ {
+ return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
+ }
+
+ template< class Char, std::size_t sz >
+ inline iterator_range<const Char*> as_literal( const Char (&arr)[sz] )
+ {
+ return range_detail::make_range( arr, range_detail::is_char_ptr(arr) );
+ }
+}
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+#endif
diff --git a/src/boost/range/atl.hpp b/src/boost/range/atl.hpp
new file mode 100644
index 0000000..ab492d9
--- /dev/null
+++ b/src/boost/range/atl.hpp
@@ -0,0 +1,733 @@
+#ifndef BOOST_RANGE_ATL_HPP
+#define BOOST_RANGE_ATL_HPP
+
+
+
+
+// Boost.Range ATL Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+
+// config
+//
+
+
+#include <atldef.h> // _ATL_VER
+
+
+#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+ #if (_ATL_VER < 0x0700)
+ #define BOOST_RANGE_ATL_NO_COLLECTIONS
+ #endif
+#endif
+
+
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+ #if (_ATL_VER < 0x0700) // dubious
+ #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX
+ #endif
+#endif
+
+
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
+ #if (_MSC_VER < 1310) // from <boost/regex/mfc.hpp>, but dubious
+ #define BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING
+ #endif
+#endif
+
+
+
+
+// forward declarations
+//
+
+
+#include <basetyps.h> // IID
+
+
+namespace ATL {
+
+
+#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+ // arrays
+ //
+ template< class E, class ETraits >
+ class CAtlArray;
+
+ template< class E >
+ class CAutoPtrArray;
+
+ template< class I, const IID *piid >
+ class CInterfaceArray;
+
+
+ // lists
+ //
+ template< class E, class ETraits >
+ class CAtlList;
+
+ template< class E >
+ class CAutoPtrList;
+
+ template< class E, class Allocator >
+ class CHeapPtrList;
+
+ template< class I, const IID *piid >
+ class CInterfaceList;
+
+
+ // maps
+ //
+ template< class K, class V, class KTraits, class VTraits >
+ class CAtlMap;
+
+ template< class K, class V, class KTraits, class VTraits >
+ class CRBTree;
+
+ template< class K, class V, class KTraits, class VTraits >
+ class CRBMap;
+
+ template< class K, class V, class KTraits, class VTraits >
+ class CRBMultiMap;
+
+
+ // strings
+ //
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
+ template< class BaseType, bool t_bMFCDLL >
+ class CSimpleStringT;
+#else
+ template< class BaseType >
+ class CSimpleStringT;
+#endif
+
+ template< class BaseType, class StringTraits >
+ class CStringT;
+
+ template< class StringType, int t_nChars >
+ class CFixedStringT;
+
+ template< class BaseType, const int t_nSize >
+ class CStaticString;
+
+
+#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+ // simples
+ //
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+ template< class T, class TEqual >
+ class CSimpleArray;
+
+ template< class TKey, class TVal, class TEqual >
+ class CSimpleMap;
+
+#else
+
+ template< class T >
+ class CSimpleArray;
+
+ template< class T >
+ class CSimpleValArray;
+
+ template< class TKey, class TVal >
+ class CSimpleMap;
+
+#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+
+ // pointers
+ //
+ template< class E >
+ class CAutoPtr;
+
+ template< class T >
+ class CComPtr;
+
+ template< class T, const IID *piid >
+ class CComQIPtr;
+
+ template< class E, class Allocator >
+ class CHeapPtr;
+
+ template< class T >
+ class CAdapt;
+
+
+} // namespace ATL
+
+
+
+
+// indirect_iterator customizations
+//
+
+
+#include <boost/mpl/identity.hpp>
+#include <boost/pointee.hpp>
+
+
+namespace boost {
+
+
+ template< class E >
+ struct pointee< ATL::CAutoPtr<E> > :
+ mpl::identity<E>
+ { };
+
+ template< class T >
+ struct pointee< ATL::CComPtr<T> > :
+ mpl::identity<T>
+ { };
+
+ template< class T, const IID *piid >
+ struct pointee< ATL::CComQIPtr<T, piid> > :
+ mpl::identity<T>
+ { };
+
+ template< class E, class Allocator >
+ struct pointee< ATL::CHeapPtr<E, Allocator> > :
+ mpl::identity<E>
+ { };
+
+ template< class T >
+ struct pointee< ATL::CAdapt<T> > :
+ pointee<T>
+ { };
+
+
+} // namespace boost
+
+
+
+
+// extended customizations
+//
+
+
+#include <boost/iterator/indirect_iterator.hpp>
+#include <boost/iterator/zip_iterator.hpp>
+#include <boost/range/detail/microsoft.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <atlbase.h> // CComBSTR
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+ // arrays
+ //
+
+ struct atl_array_functions :
+ array_functions
+ {
+ template< class Iterator, class X >
+ Iterator end(X& x) // redefine
+ {
+ return x.GetData() + x.GetCount(); // no 'GetSize()'
+ }
+ };
+
+
+ template< class E, class ETraits >
+ struct customization< ATL::CAtlArray<E, ETraits> > :
+ atl_array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef E val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+ template< class E >
+ struct customization< ATL::CAutoPtrArray<E> > :
+ atl_array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ // ATL::CAutoPtr/CHeapPtr is no assignable.
+ typedef ATL::CAutoPtr<E> val_t;
+ typedef val_t *miter_t;
+ typedef val_t const *citer_t;
+
+ typedef indirect_iterator<miter_t> mutable_iterator;
+ typedef indirect_iterator<citer_t> const_iterator;
+ };
+ };
+
+
+ template< class I, const IID *piid >
+ struct customization< ATL::CInterfaceArray<I, piid> > :
+ atl_array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef ATL::CComQIPtr<I, piid> val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+ template< class E, class ETraits >
+ struct customization< ATL::CAtlList<E, ETraits> > :
+ list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef E val_t;
+
+ typedef list_iterator<X, val_t> mutable_iterator;
+ typedef list_iterator<X const, val_t const> const_iterator;
+ };
+ };
+
+
+ struct indirected_list_functions
+ {
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ typedef typename Iterator::base_type base_t; // == list_iterator
+ return Iterator(base_t(x, x.GetHeadPosition()));
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ typedef typename Iterator::base_type base_t;
+ return Iterator(base_t(x, POSITION(0)));
+ }
+ };
+
+
+ template< class E >
+ struct customization< ATL::CAutoPtrList<E> > :
+ indirected_list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef ATL::CAutoPtr<E> val_t;
+ typedef list_iterator<X, val_t> miter_t;
+ typedef list_iterator<X const, val_t const> citer_t;
+
+ typedef indirect_iterator<miter_t> mutable_iterator;
+ typedef indirect_iterator<citer_t> const_iterator;
+ };
+ };
+
+
+ template< class E, class Allocator >
+ struct customization< ATL::CHeapPtrList<E, Allocator> > :
+ indirected_list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef ATL::CHeapPtr<E, Allocator> val_t;
+ typedef list_iterator<X, val_t> miter_t;
+ typedef list_iterator<X const, val_t const> citer_t;
+
+ typedef indirect_iterator<miter_t> mutable_iterator;
+ typedef indirect_iterator<citer_t> const_iterator;
+ };
+ };
+
+
+ template< class I, const IID *piid >
+ struct customization< ATL::CInterfaceList<I, piid> > :
+ list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef ATL::CComQIPtr<I, piid> val_t;
+
+ typedef list_iterator<X, val_t> mutable_iterator;
+ typedef list_iterator<X const, val_t const> const_iterator;
+ };
+ };
+
+
+ // maps
+ //
+
+ struct atl_rb_tree_tag
+ { };
+
+ template< >
+ struct customization< atl_rb_tree_tag > :
+ indirected_list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef typename X::CPair val_t;
+
+ typedef list_iterator<X, val_t *, val_t *> miter_t;
+ typedef list_iterator<X const, val_t const *, val_t const *> citer_t;
+
+ typedef indirect_iterator<miter_t> mutable_iterator;
+ typedef indirect_iterator<citer_t> const_iterator;
+ };
+ };
+
+
+ template< class K, class V, class KTraits, class VTraits >
+ struct customization< ATL::CAtlMap<K, V, KTraits, VTraits> > :
+ customization< atl_rb_tree_tag >
+ {
+ template< class Iterator, class X >
+ Iterator begin(X& x) // redefine
+ {
+ typedef typename Iterator::base_type base_t; // == list_iterator
+ return Iterator(base_t(x, x.GetStartPosition())); // no 'GetHeadPosition'
+ }
+ };
+
+
+ // strings
+ //
+
+ struct atl_string_tag
+ { };
+
+ template< >
+ struct customization< atl_string_tag >
+ {
+ template< class X >
+ struct meta
+ {
+ typedef typename X::PXSTR mutable_iterator;
+ typedef typename X::PCXSTR const_iterator;
+ };
+
+ template< class Iterator, class X >
+ typename mutable_<Iterator, X>::type begin(X& x)
+ {
+ return x.GetBuffer(0);
+ }
+
+ template< class Iterator, class X >
+ Iterator begin(X const& x)
+ {
+ return x.GetString();
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return begin<Iterator>(x) + x.GetLength();
+ }
+ };
+
+
+ template< class BaseType, const int t_nSize >
+ struct customization< ATL::CStaticString<BaseType, t_nSize> >
+ {
+ template< class X >
+ struct meta
+ {
+ typedef BaseType const *mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ };
+
+ template< class Iterator, class X >
+ Iterator begin(X const& x)
+ {
+ return x;
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X const& x)
+ {
+ return begin<Iterator>(x) + X::GetLength();
+ }
+ };
+
+
+#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+ template< >
+ struct customization< ATL::CComBSTR >
+ {
+ template< class X >
+ struct meta
+ {
+ typedef OLECHAR *mutable_iterator;
+ typedef OLECHAR const *const_iterator;
+ };
+
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ return x.operator BSTR();
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return begin<Iterator>(x) + x.Length();
+ }
+ };
+
+
+ // simples
+ //
+
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+ template< class T, class TEqual >
+ struct customization< ATL::CSimpleArray<T, TEqual> > :
+#else
+ template< class T >
+ struct customization< ATL::CSimpleArray<T> > :
+#endif
+ array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef T val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+#if defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+ template< class T >
+ struct customization< ATL::CSimpleValArray<T> > :
+ array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef T val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+#endif // defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+ template< class TKey, class TVal, class TEqual >
+ struct customization< ATL::CSimpleMap<TKey, TVal, TEqual> >
+#else
+ template< class TKey, class TVal >
+ struct customization< ATL::CSimpleMap<TKey, TVal> >
+#endif
+ {
+ template< class X >
+ struct meta
+ {
+ typedef TKey k_val_t;
+ typedef k_val_t *k_miter_t;
+ typedef k_val_t const *k_citer_t;
+
+ typedef TVal v_val_t;
+ typedef v_val_t *v_miter_t;
+ typedef v_val_t const *v_citer_t;
+
+ // Topic:
+ // 'std::pair' can't contain references
+ // because of reference to reference problem.
+
+ typedef zip_iterator< tuple<k_miter_t, v_miter_t> > mutable_iterator;
+ typedef zip_iterator< tuple<k_citer_t, v_citer_t> > const_iterator;
+ };
+
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ return Iterator(boost::make_tuple(x.m_aKey, x.m_aVal));
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return Iterator(boost::make_tuple(x.m_aKey + x.GetSize(), x.m_aVal + x.GetSize()));
+ }
+ };
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+
+
+// range customizations
+//
+
+
+#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+ // arrays
+ //
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CAtlArray, 2
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CAutoPtrArray, 1
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CInterfaceArray, (class)(const IID *)
+ )
+
+
+ // lists
+ //
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CAtlList, 2
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CAutoPtrList, 1
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CHeapPtrList, 2
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CInterfaceList, (class)(const IID *)
+ )
+
+
+ //maps
+ //
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CAtlMap, 4
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::atl_rb_tree_tag,
+ (ATL, BOOST_PP_NIL), CRBTree, 4
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::atl_rb_tree_tag,
+ (ATL, BOOST_PP_NIL), CRBMap, 4
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::atl_rb_tree_tag,
+ (ATL, BOOST_PP_NIL), CRBMultiMap, 4
+ )
+
+
+ // strings
+ //
+ #if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING)
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::atl_string_tag,
+ (ATL, BOOST_PP_NIL), CSimpleStringT, (class)(bool)
+ )
+ #else
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::atl_string_tag,
+ (ATL, BOOST_PP_NIL), CSimpleStringT, 1
+ )
+ #endif
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::atl_string_tag,
+ (ATL, BOOST_PP_NIL), CStringT, 2
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::atl_string_tag,
+ (ATL, BOOST_PP_NIL), CFixedStringT, (class)(int)
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CStaticString, (class)(const int)
+ )
+
+
+#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS)
+
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CComBSTR
+)
+
+
+// simples
+//
+#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CSimpleArray, 2
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CSimpleMap, 3
+ )
+
+#else
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CSimpleArray, 1
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CSimpleMap, 2
+ )
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ (ATL, BOOST_PP_NIL), CSimpleValArray, 1
+ )
+
+#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX)
+
+
+
+
+#endif
diff --git a/src/boost/range/begin.hpp b/src/boost/range/begin.hpp
new file mode 100644
index 0000000..c668488
--- /dev/null
+++ b/src/boost/range/begin.hpp
@@ -0,0 +1,143 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_BEGIN_HPP
+#define BOOST_RANGE_BEGIN_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+#include <boost/range/detail/begin.hpp>
+#else
+
+#include <boost/range/iterator.hpp>
+
+namespace boost
+{
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+namespace range_detail
+{
+#endif
+
+ //////////////////////////////////////////////////////////////////////
+ // primary template
+ //////////////////////////////////////////////////////////////////////
+
+ template< typename C >
+ inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
+ range_begin( C& c )
+ {
+ //
+ // If you get a compile-error here, it is most likely because
+ // you have not implemented range_begin() properly in
+ // the namespace of C
+ //
+ return c.begin();
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template< typename Iterator >
+ inline Iterator range_begin( const std::pair<Iterator,Iterator>& p )
+ {
+ return p.first;
+ }
+
+ template< typename Iterator >
+ inline Iterator range_begin( std::pair<Iterator,Iterator>& p )
+ {
+ return p.first;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////
+
+ //
+ // May this be discarded? Or is it needed for bad compilers?
+ //
+ template< typename T, std::size_t sz >
+ inline const T* range_begin( const T (&a)[sz] )
+ {
+ return a;
+ }
+
+ template< typename T, std::size_t sz >
+ inline T* range_begin( T (&a)[sz] )
+ {
+ return a;
+ }
+
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+} // namespace 'range_detail'
+#endif
+
+// Use a ADL namespace barrier to avoid ambiguity with other unqualified
+// calls. This is particularly important with C++0x encouraging
+// unqualified calls to begin/end.
+namespace range_adl_barrier
+{
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
+{
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+ using namespace range_detail;
+#endif
+ return range_begin( r );
+}
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
+{
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+ using namespace range_detail;
+#endif
+ return range_begin( r );
+}
+
+ } // namespace range_adl_barrier
+} // namespace boost
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+namespace boost
+{
+ namespace range_adl_barrier
+ {
+ template< class T >
+ inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
+ const_begin( const T& r )
+ {
+ return boost::range_adl_barrier::begin( r );
+ }
+ } // namespace range_adl_barrier
+
+ using namespace range_adl_barrier;
+} // namespace boost
+
+#endif
+
diff --git a/src/boost/range/category.hpp b/src/boost/range/category.hpp
new file mode 100644
index 0000000..1574605
--- /dev/null
+++ b/src/boost/range/category.hpp
@@ -0,0 +1,29 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CATEGORY_HPP
+#define BOOST_RANGE_CATEGORY_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+ template< class T >
+ struct range_category : iterator_category< typename range_iterator<T>::type >
+ { };
+}
+
+#endif
diff --git a/src/boost/range/combine.hpp b/src/boost/range/combine.hpp
new file mode 100644
index 0000000..999bbc3
--- /dev/null
+++ b/src/boost/range/combine.hpp
@@ -0,0 +1,304 @@
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_COMBINE_HPP
+#define BOOST_RANGE_COMBINE_HPP
+
+#include <boost/iterator/zip_iterator.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/plus.hpp>
+#include <boost/mpl/arithmetic.hpp>
+#include <boost/config.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ struct void_ { typedef void_ type; };
+ }
+
+ template<> struct range_iterator< ::boost::range_detail::void_ >
+ {
+ typedef ::boost::tuples::null_type type;
+ };
+
+ namespace range_detail
+ {
+ inline ::boost::tuples::null_type range_begin( ::boost::range_detail::void_& )
+ { return ::boost::tuples::null_type(); }
+
+ inline ::boost::tuples::null_type range_begin( const ::boost::range_detail::void_& )
+ { return ::boost::tuples::null_type(); }
+
+ inline ::boost::tuples::null_type range_end( ::boost::range_detail::void_& )
+ { return ::boost::tuples::null_type(); }
+
+ inline ::boost::tuples::null_type range_end( const ::boost::range_detail::void_& )
+ { return ::boost::tuples::null_type(); }
+
+ template< class T >
+ struct tuple_iter
+ {
+ typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c<
+ ::boost::is_same<T, ::boost::range_detail::void_ >::value,
+ ::boost::mpl::identity< ::boost::tuples::null_type >,
+ ::boost::range_iterator<T>
+ >::type type;
+ };
+
+ template< class Rng1, class Rng2 >
+ struct tuple_range
+ {
+ typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c<
+ ::boost::is_same<Rng1, ::boost::range_detail::void_ >::value,
+ ::boost::range_detail::void_,
+ ::boost::mpl::identity<Rng1>
+ >::type type;
+ };
+
+ template
+ <
+ class R1,
+ class R2,
+ class R3,
+ class R4,
+ class R5,
+ class R6
+ >
+ struct generate_tuple
+ {
+ typedef ::boost::tuples::tuple<
+ BOOST_DEDUCED_TYPENAME tuple_iter<R1>::type,
+ BOOST_DEDUCED_TYPENAME tuple_iter<R2>::type,
+ BOOST_DEDUCED_TYPENAME tuple_iter<R3>::type,
+ BOOST_DEDUCED_TYPENAME tuple_iter<R4>::type,
+ BOOST_DEDUCED_TYPENAME tuple_iter<R5>::type,
+ BOOST_DEDUCED_TYPENAME tuple_iter<R6>::type
+ > type;
+
+ static type begin( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
+ {
+ return ::boost::tuples::make_tuple( ::boost::begin(r1),
+ ::boost::begin(r2),
+ ::boost::begin(r3),
+ ::boost::begin(r4),
+ ::boost::begin(r5),
+ ::boost::begin(r6) );
+ }
+
+ static type end( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
+ {
+ return ::boost::tuples::make_tuple( ::boost::end(r1),
+ ::boost::end(r2),
+ ::boost::end(r3),
+ ::boost::end(r4),
+ ::boost::end(r5),
+ ::boost::end(r6) );
+ }
+ };
+
+ template
+ <
+ class R1,
+ class R2 = void_,
+ class R3 = void_,
+ class R4 = void_,
+ class R5 = void_,
+ class R6 = void_
+ >
+ struct zip_rng
+ : iterator_range<
+ zip_iterator<
+ BOOST_DEDUCED_TYPENAME generate_tuple<R1,R2,R3,R4,R5,R6>::type
+ >
+ >
+ {
+ private:
+ typedef generate_tuple<R1,R2,R3,R4,R5,R6> generator_t;
+ typedef BOOST_DEDUCED_TYPENAME generator_t::type tuple_t;
+ typedef zip_iterator<tuple_t> zip_iter_t;
+ typedef iterator_range<zip_iter_t> base_t;
+
+ public:
+ zip_rng( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
+ : base_t( zip_iter_t( generator_t::begin(r1,r2,r3,r4,r5,r6) ),
+ zip_iter_t( generator_t::end(r1,r2,r3,r4,r5,r6) ) )
+ {
+ BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
+ BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3));
+ BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r4));
+ BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r5));
+ BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r6));
+ }
+
+ template< class Zip, class Rng >
+ zip_rng( Zip& z, Rng& r )
+ : base_t( zip_iter_t( generator_t::begin( z, r ) ),
+ zip_iter_t( generator_t::end( z, r ) ) )
+ {
+
+ // @todo: tuple::begin( should be overloaded for this situation
+ }
+
+ struct tuple_length : ::boost::tuples::length<tuple_t>
+ { };
+
+ template< unsigned N >
+ struct get
+ {
+ template< class Z, class R >
+ static BOOST_DEDUCED_TYPENAME ::boost::tuples::element<N,tuple_t>::type begin( Z& z, R& )
+ {
+ return get<N>( z.begin().get_iterator_tuple() );
+ }
+
+ template< class Z, class R >
+ static BOOST_DEDUCED_TYPENAME ::boost::tuples::element<N,tuple_t>::type end( Z& z, R& r )
+ {
+ return get<N>( z.end().get_iterator_tuple() );
+ }
+ };
+
+ };
+
+ template< class Rng1, class Rng2 >
+ struct zip_range
+ : iterator_range<
+ zip_iterator<
+ ::boost::tuples::tuple<
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type
+ >
+ >
+ >
+ {
+ private:
+ typedef zip_iterator<
+ ::boost::tuples::tuple<
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type
+ >
+ > zip_iter_t;
+ typedef iterator_range<zip_iter_t> base_t;
+
+ public:
+ zip_range( Rng1& r1, Rng2& r2 )
+ : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1),
+ ::boost::begin(r2)) ),
+ zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1),
+ ::boost::end(r2)) ) )
+ {
+ BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
+ }
+ };
+
+ template< class Rng1, class Rng2, class Rng3 >
+ struct zip_range3
+ : iterator_range<
+ zip_iterator<
+ ::boost::tuples::tuple<
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type,
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng3>::type
+ >
+ >
+ >
+ {
+ private:
+ typedef zip_iterator<
+ ::boost::tuples::tuple<
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type,
+ BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng3>::type
+ >
+ > zip_iter_t;
+ typedef iterator_range<zip_iter_t> base_t;
+
+ public:
+ zip_range3( Rng1& r1, Rng2& r2, Rng3& r3 )
+ : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1),
+ ::boost::begin(r2),
+ ::boost::begin(r3)) ),
+ zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1),
+ ::boost::end(r2),
+ ::boost::end(r3)) )
+ )
+ {
+ BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
+ BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3));
+ }
+ };
+
+
+ struct combine_tag {};
+
+ template< class Rng >
+ inline zip_rng<Rng>
+ operator&( combine_tag, Rng& r )
+ {
+ return zip_rng<Rng>(r);
+ }
+
+ template< class Rng >
+ inline iterator_range<const Rng>
+ operator&( combine_tag, const Rng& r )
+ {
+ return iterator_range<const Rng>(r);
+ }
+
+ template
+ <
+ class R1,
+ class R2,
+ class R3,
+ class R4,
+ class R5,
+ class Rng
+ >
+ inline BOOST_DEDUCED_TYPENAME zip_rng<R1,R2,R3,R4,R5>::next
+ operator&( const zip_rng<R1,R2,R3,R4,R5>& zip,
+ Rng& r )
+ {
+ return zip_rng<R1,R2,R3,R4,R5>::next( zip, r );
+ }
+
+ } // namespace range_detail
+
+ template< class Rng1, class Rng2 >
+ inline ::boost::range_detail::zip_range<Rng1, Rng2> combine( Rng1& r1, Rng2& r2 )
+ {
+ return ::boost::range_detail::zip_range<Rng1, Rng2>(r1, r2);
+ }
+
+ template< class Rng1, class Rng2 >
+ inline ::boost::range_detail::zip_range<const Rng1, Rng2> combine( const Rng1& r1, Rng2& r2 )
+ {
+ return ::boost::range_detail::zip_range<const Rng1, Rng2>(r1, r2);
+ }
+
+ template< class Rng1, class Rng2 >
+ inline ::boost::range_detail::zip_range<Rng1, const Rng2> combine( Rng1& r1, const Rng2& r2 )
+ {
+ return ::boost::range_detail::zip_range<Rng1, const Rng2>(r1, r2);
+ }
+
+ template< class Rng1, class Rng2 >
+ inline ::boost::range_detail::zip_range<const Rng1, const Rng2> combine( const Rng1& r1, const Rng2& r2 )
+ {
+ return ::boost::range_detail::zip_range<const Rng1, const Rng2>(r1, r2);
+ }
+
+} // namespace boost
+
+#endif
diff --git a/src/boost/range/concepts.hpp b/src/boost/range/concepts.hpp
new file mode 100644
index 0000000..5965293
--- /dev/null
+++ b/src/boost/range/concepts.hpp
@@ -0,0 +1,366 @@
+// Boost.Range library concept checks
+//
+// Copyright Neil Groves 2009. Use, modification and distribution
+// are subject to the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Copyright Daniel Walker 2006. Use, modification and distribution
+// are subject to the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CONCEPTS_HPP
+#define BOOST_RANGE_CONCEPTS_HPP
+
+#include <boost/concept_check.hpp>
+#include <boost/iterator/iterator_concepts.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/detail/misc_concept.hpp>
+
+/*!
+ * \file
+ * \brief Concept checks for the Boost Range library.
+ *
+ * The structures in this file may be used in conjunction with the
+ * Boost Concept Check library to insure that the type of a function
+ * parameter is compatible with a range concept. If not, a meaningful
+ * compile time error is generated. Checks are provided for the range
+ * concepts related to iterator traversal categories. For example, the
+ * following line checks that the type T models the ForwardRange
+ * concept.
+ *
+ * \code
+ * BOOST_CONCEPT_ASSERT((ForwardRangeConcept<T>));
+ * \endcode
+ *
+ * A different concept check is required to ensure writeable value
+ * access. For example to check for a ForwardRange that can be written
+ * to, the following code is required.
+ *
+ * \code
+ * BOOST_CONCEPT_ASSERT((WriteableForwardRangeConcept<T>));
+ * \endcode
+ *
+ * \see http://www.boost.org/libs/range/doc/range.html for details
+ * about range concepts.
+ * \see http://www.boost.org/libs/iterator/doc/iterator_concepts.html
+ * for details about iterator concepts.
+ * \see http://www.boost.org/libs/concept_check/concept_check.htm for
+ * details about concept checks.
+ */
+
+namespace boost {
+
+ namespace range_detail {
+
+#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+
+// List broken compiler versions here:
+ #ifdef __GNUC__
+ // GNUC 4.2 has strange issues correctly detecting compliance with the Concepts
+ // hence the least disruptive approach is to turn-off the concept checking for
+ // this version of the compiler.
+ #if __GNUC__ == 4 && __GNUC_MINOR__ == 2
+ #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
+ #endif
+ #endif
+
+ #ifdef __BORLANDC__
+ #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
+ #endif
+
+ #ifdef __PATHCC__
+ #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
+ #endif
+
+// Default to using the concept asserts unless we have defined it off
+// during the search for black listed compilers.
+ #ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 1
+ #endif
+
+#endif
+
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ #define BOOST_RANGE_CONCEPT_ASSERT( x ) BOOST_CONCEPT_ASSERT( x )
+#else
+ #define BOOST_RANGE_CONCEPT_ASSERT( x )
+#endif
+
+ // Rationale for the inclusion of redefined iterator concept
+ // classes:
+ //
+ // The Range algorithms often do not require that the iterators are
+ // Assignable or default constructable, but the correct standard
+ // conformant iterators do require the iterators to be a model of the
+ // Assignable concept.
+ // Iterators that contains a functor that is not assignable therefore
+ // are not correct models of the standard iterator concepts,
+ // despite being adequate for most algorithms. An example of this
+ // use case is the combination of the boost::adaptors::filtered
+ // class with a boost::lambda::bind generated functor.
+ // Ultimately modeling the range concepts using composition
+ // with the Boost.Iterator concepts would render the library
+ // incompatible with many common Boost.Lambda expressions.
+ template<class Iterator>
+ struct IncrementableIteratorConcept : CopyConstructible<Iterator>
+ {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ typedef BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator>::type traversal_category;
+
+ BOOST_RANGE_CONCEPT_ASSERT((
+ Convertible<
+ traversal_category,
+ incrementable_traversal_tag
+ >));
+
+ BOOST_CONCEPT_USAGE(IncrementableIteratorConcept)
+ {
+ ++i;
+ (void)i++;
+ }
+ private:
+ Iterator i;
+#endif
+ };
+
+ template<class Iterator>
+ struct SinglePassIteratorConcept
+ : IncrementableIteratorConcept<Iterator>
+ , EqualityComparable<Iterator>
+ {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ BOOST_RANGE_CONCEPT_ASSERT((
+ Convertible<
+ BOOST_DEDUCED_TYPENAME SinglePassIteratorConcept::traversal_category,
+ single_pass_traversal_tag
+ >));
+
+ BOOST_CONCEPT_USAGE(SinglePassIteratorConcept)
+ {
+ Iterator i2(++i);
+ boost::ignore_unused_variable_warning(i2);
+
+ // deliberately we are loose with the postfix version for the single pass
+ // iterator due to the commonly poor adherence to the specification means that
+ // many algorithms would be unusable, whereas actually without the check they
+ // work
+ (void)(i++);
+
+ BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r1(*i);
+ boost::ignore_unused_variable_warning(r1);
+
+ BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r2(*(++i));
+ boost::ignore_unused_variable_warning(r2);
+ }
+ private:
+ Iterator i;
+#endif
+ };
+
+ template<class Iterator>
+ struct ForwardIteratorConcept
+ : SinglePassIteratorConcept<Iterator>
+ , DefaultConstructible<Iterator>
+ {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::difference_type difference_type;
+
+ BOOST_MPL_ASSERT((is_integral<difference_type>));
+ BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
+
+ BOOST_RANGE_CONCEPT_ASSERT((
+ Convertible<
+ BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
+ forward_traversal_tag
+ >));
+
+ BOOST_CONCEPT_USAGE(ForwardIteratorConcept)
+ {
+ // See the above note in the SinglePassIteratorConcept about the handling of the
+ // postfix increment. Since with forward and better iterators there is no need
+ // for a proxy, we can sensibly require that the dereference result
+ // is convertible to reference.
+ Iterator i2(i++);
+ boost::ignore_unused_variable_warning(i2);
+ BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference r(*(i++));
+ boost::ignore_unused_variable_warning(r);
+ }
+ private:
+ Iterator i;
+#endif
+ };
+
+ template<class Iterator>
+ struct BidirectionalIteratorConcept
+ : ForwardIteratorConcept<Iterator>
+ {
+ #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ BOOST_RANGE_CONCEPT_ASSERT((
+ Convertible<
+ BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::traversal_category,
+ bidirectional_traversal_tag
+ >));
+
+ BOOST_CONCEPT_USAGE(BidirectionalIteratorConcept)
+ {
+ --i;
+ (void)i--;
+ }
+ private:
+ Iterator i;
+ #endif
+ };
+
+ template<class Iterator>
+ struct RandomAccessIteratorConcept
+ : BidirectionalIteratorConcept<Iterator>
+ {
+ #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ BOOST_RANGE_CONCEPT_ASSERT((
+ Convertible<
+ BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::traversal_category,
+ random_access_traversal_tag
+ >));
+
+ BOOST_CONCEPT_USAGE(RandomAccessIteratorConcept)
+ {
+ i += n;
+ i = i + n;
+ i = n + i;
+ i -= n;
+ i = i - n;
+ n = i - j;
+ }
+ private:
+ BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::difference_type n;
+ Iterator i;
+ Iterator j;
+ #endif
+ };
+
+ } // namespace range_detail
+
+ //! Check if a type T models the SinglePassRange range concept.
+ template<class T>
+ struct SinglePassRangeConcept
+ {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<T const>::type const_iterator;
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<T>::type iterator;
+
+ BOOST_RANGE_CONCEPT_ASSERT((range_detail::SinglePassIteratorConcept<iterator>));
+ BOOST_RANGE_CONCEPT_ASSERT((range_detail::SinglePassIteratorConcept<const_iterator>));
+
+ BOOST_CONCEPT_USAGE(SinglePassRangeConcept)
+ {
+ // This has been modified from assigning to this->i
+ // (where i was a member variable) to improve
+ // compatibility with Boost.Lambda
+ iterator i1 = boost::begin(*m_range);
+ iterator i2 = boost::end(*m_range);
+
+ ignore_unused_variable_warning(i1);
+ ignore_unused_variable_warning(i2);
+
+ const_constraints(*m_range);
+ }
+
+ private:
+ void const_constraints(const T& const_range)
+ {
+ const_iterator ci1 = boost::begin(const_range);
+ const_iterator ci2 = boost::end(const_range);
+
+ ignore_unused_variable_warning(ci1);
+ ignore_unused_variable_warning(ci2);
+ }
+
+ // Rationale:
+ // The type of m_range is T* rather than T because it allows
+ // T to be an abstract class. The other obvious alternative of
+ // T& produces a warning on some compilers.
+ T* m_range;
+#endif
+ };
+
+ //! Check if a type T models the ForwardRange range concept.
+ template<class T>
+ struct ForwardRangeConcept : SinglePassRangeConcept<T>
+ {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::iterator>));
+ BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::const_iterator>));
+#endif
+ };
+
+ template<class Range>
+ struct WriteableRangeConcept
+ {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<Range>::type iterator;
+
+ BOOST_CONCEPT_USAGE(WriteableRangeConcept)
+ {
+ *i = v;
+ }
+ private:
+ iterator i;
+ BOOST_DEDUCED_TYPENAME range_value<Range>::type v;
+#endif
+ };
+
+ //! Check if a type T models the WriteableForwardRange range concept.
+ template<class T>
+ struct WriteableForwardRangeConcept
+ : ForwardRangeConcept<T>
+ , WriteableRangeConcept<T>
+ {
+ };
+
+ //! Check if a type T models the BidirectionalRange range concept.
+ template<class T>
+ struct BidirectionalRangeConcept : ForwardRangeConcept<T>
+ {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ BOOST_RANGE_CONCEPT_ASSERT((BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::iterator>));
+ BOOST_RANGE_CONCEPT_ASSERT((BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::const_iterator>));
+#endif
+ };
+
+ //! Check if a type T models the WriteableBidirectionalRange range concept.
+ template<class T>
+ struct WriteableBidirectionalRangeConcept
+ : BidirectionalRangeConcept<T>
+ , WriteableRangeConcept<T>
+ {
+ };
+
+ //! Check if a type T models the RandomAccessRange range concept.
+ template<class T>
+ struct RandomAccessRangeConcept : BidirectionalRangeConcept<T>
+ {
+#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
+ BOOST_RANGE_CONCEPT_ASSERT((RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::iterator>));
+ BOOST_RANGE_CONCEPT_ASSERT((RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::const_iterator>));
+#endif
+ };
+
+ //! Check if a type T models the WriteableRandomAccessRange range concept.
+ template<class T>
+ struct WriteableRandomAccessRangeConcept
+ : RandomAccessRangeConcept<T>
+ , WriteableRangeConcept<T>
+ {
+ };
+
+} // namespace boost
+
+#endif // BOOST_RANGE_CONCEPTS_HPP
diff --git a/src/boost/range/config.hpp b/src/boost/range/config.hpp
new file mode 100644
index 0000000..4e7fb24
--- /dev/null
+++ b/src/boost/range/config.hpp
@@ -0,0 +1,54 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CONFIG_HPP
+#define BOOST_RANGE_CONFIG_HPP
+
+#include <boost/detail/workaround.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_RANGE_DEDUCED_TYPENAME
+#error "macro already defined!"
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# define BOOST_RANGE_DEDUCED_TYPENAME typename
+#else
+# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) && !defined(_MSC_EXTENSIONS)
+# define BOOST_RANGE_DEDUCED_TYPENAME typename
+# else
+# define BOOST_RANGE_DEDUCED_TYPENAME BOOST_DEDUCED_TYPENAME
+# endif
+#endif
+
+#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
+#error "macro already defined!"
+#endif
+
+#if BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) || BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
+#define BOOST_RANGE_NO_ARRAY_SUPPORT 1
+#endif
+
+#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
+#define BOOST_RANGE_ARRAY_REF() (boost_range_array)
+#define BOOST_RANGE_NO_STATIC_ASSERT
+#else
+#define BOOST_RANGE_ARRAY_REF() (&boost_range_array)
+#endif
+
+
+
+#endif
+
diff --git a/src/boost/range/const_iterator.hpp b/src/boost/range/const_iterator.hpp
new file mode 100644
index 0000000..875320f
--- /dev/null
+++ b/src/boost/range/const_iterator.hpp
@@ -0,0 +1,67 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CONST_ITERATOR_HPP
+#define BOOST_RANGE_CONST_ITERATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#include <boost/range/detail/const_iterator.hpp>
+#else
+
+#include <boost/range/detail/extract_optional_type.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <cstddef>
+#include <utility>
+
+namespace boost
+{
+ //////////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////////
+
+ namespace range_detail {
+ BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( const_iterator )
+ }
+
+ template< typename C >
+ struct range_const_iterator : range_detail::extract_const_iterator<C>
+ {};
+
+ //////////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////////
+
+ template< typename Iterator >
+ struct range_const_iterator< std::pair<Iterator,Iterator> >
+ {
+ typedef Iterator type;
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////////
+
+ template< typename T, std::size_t sz >
+ struct range_const_iterator< T[sz] >
+ {
+ typedef const T* type;
+ };
+
+} // namespace boost
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#endif
diff --git a/src/boost/range/const_reverse_iterator.hpp b/src/boost/range/const_reverse_iterator.hpp
new file mode 100644
index 0000000..215bcc7
--- /dev/null
+++ b/src/boost/range/const_reverse_iterator.hpp
@@ -0,0 +1,32 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP
+#define BOOST_RANGE_CONST_REVERSE_ITERATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/reverse_iterator.hpp>
+
+namespace boost
+{
+ //
+ // This interface is deprecated, use range_reverse_iterator<const T>
+ //
+
+ template< typename C >
+ struct range_const_reverse_iterator : range_reverse_iterator<const C>
+ { };
+
+} // namespace boost
+
+#endif
diff --git a/src/boost/range/counting_range.hpp b/src/boost/range/counting_range.hpp
new file mode 100644
index 0000000..b8e4e3a
--- /dev/null
+++ b/src/boost/range/counting_range.hpp
@@ -0,0 +1,66 @@
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_COUNTING_RANGE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#if BOOST_MSVC >= 1400
+#pragma warning(push)
+#pragma warning(disable : 4244)
+#endif
+
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+
+namespace boost
+{
+
+ template<class Value>
+ inline iterator_range<counting_iterator<Value> >
+ counting_range(Value first, Value last)
+ {
+ typedef counting_iterator<Value> counting_iterator_t;
+ typedef iterator_range<counting_iterator_t> result_t;
+ return result_t(counting_iterator_t(first),
+ counting_iterator_t(last));
+ }
+
+ template<class Range>
+ inline iterator_range<counting_iterator<BOOST_DEDUCED_TYPENAME range_value<const Range>::type> >
+ counting_range(const Range& rng)
+ {
+ typedef counting_iterator<BOOST_DEDUCED_TYPENAME range_value<const Range>::type> counting_iterator_t;
+ typedef iterator_range<counting_iterator_t> result_t;
+ return boost::empty(rng)
+ ? result_t()
+ : result_t(
+ counting_iterator_t(*boost::begin(rng)),
+ counting_iterator_t(*boost::prior(boost::end(rng))));
+ }
+
+ template<class Range>
+ inline iterator_range<counting_iterator<BOOST_DEDUCED_TYPENAME range_value<Range>::type> >
+ counting_range(Range& rng)
+ {
+ typedef counting_iterator<BOOST_DEDUCED_TYPENAME range_value<Range>::type> counting_iterator_t;
+ typedef iterator_range<counting_iterator_t> result_t;
+ return boost::empty(rng)
+ ? result_t()
+ : result_t(
+ counting_iterator_t(*boost::begin(rng)),
+ counting_iterator_t(*boost::prior(boost::end(rng))));
+ }
+} // namespace boost
+
+#if BOOST_MSVC >= 1400
+#pragma warning(pop)
+#endif
+
+#endif // include guard
diff --git a/src/boost/range/detail/any_iterator.hpp b/src/boost/range/detail/any_iterator.hpp
new file mode 100644
index 0000000..5705ff0
--- /dev/null
+++ b/src/boost/range/detail/any_iterator.hpp
@@ -0,0 +1,586 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
+
+#include <boost/cast.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/range/detail/any_iterator_buffer.hpp>
+#include <boost/range/detail/any_iterator_interface.hpp>
+#include <boost/range/detail/any_iterator_wrapper.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ // metafunction to determine if T is a const reference
+ template<class T>
+ struct is_const_reference
+ {
+ typedef typename mpl::and_<
+ typename is_reference<T>::type,
+ typename is_const<
+ typename remove_reference<T>::type
+ >::type
+ >::type type;
+ };
+
+ // metafunction to determine if T is a mutable reference
+ template<class T>
+ struct is_mutable_reference
+ {
+ typedef typename mpl::and_<
+ typename is_reference<T>::type,
+ typename mpl::not_<
+ typename is_const<
+ typename remove_reference<T>::type
+ >::type
+ >::type
+ >::type type;
+ };
+
+ // metafunction to evaluate if a source 'reference' can be
+ // converted to a target 'reference' as a value.
+ //
+ // This is true, when the target reference type is actually
+ // not a reference, and the source reference is convertible
+ // to the target type.
+ template<class SourceReference, class TargetReference>
+ struct is_convertible_to_value_as_reference
+ {
+ typedef typename mpl::and_<
+ typename mpl::not_<
+ typename is_reference<TargetReference>::type
+ >::type
+ , typename is_convertible<
+ SourceReference
+ , TargetReference
+ >::type
+ >::type type;
+ };
+
+ template<
+ class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer = any_iterator_default_buffer
+ >
+ class any_iterator;
+
+ // metafunction to determine if SomeIterator is an
+ // any_iterator.
+ //
+ // This is the general implementation which evaluates to false.
+ template<class SomeIterator>
+ struct is_any_iterator
+ : mpl::bool_<false>
+ {
+ };
+
+ // specialization of is_any_iterator to return true for
+ // any_iterator classes regardless of template parameters.
+ template<
+ class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct is_any_iterator<
+ any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >
+ >
+ : mpl::bool_<true>
+ {
+ };
+ } // namespace range_detail
+
+ namespace detail
+ {
+ // Rationale:
+ // These are specialized since the iterator_facade versions lack
+ // the requisite typedefs to allow wrapping to determine the types
+ // if a user copy constructs from a postfix increment.
+
+ template<
+ class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ class postfix_increment_proxy<
+ range_detail::any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >
+ >
+ {
+ typedef range_detail::any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ > any_iterator_type;
+
+ public:
+ typedef Value value_type;
+ typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
+ typedef Difference difference_type;
+ typedef typename iterator_pointer<any_iterator_type>::type pointer;
+ typedef Reference reference;
+
+ explicit postfix_increment_proxy(any_iterator_type const& x)
+ : stored_value(*x)
+ {}
+
+ value_type&
+ operator*() const
+ {
+ return this->stored_value;
+ }
+ private:
+ mutable value_type stored_value;
+ };
+
+ template<
+ class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ class writable_postfix_increment_proxy<
+ range_detail::any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >
+ >
+ {
+ typedef range_detail::any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ > any_iterator_type;
+ public:
+ typedef Value value_type;
+ typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
+ typedef Difference difference_type;
+ typedef typename iterator_pointer<any_iterator_type>::type pointer;
+ typedef Reference reference;
+
+ explicit writable_postfix_increment_proxy(any_iterator_type const& x)
+ : stored_value(*x)
+ , stored_iterator(x)
+ {}
+
+ // Dereferencing must return a proxy so that both *r++ = o and
+ // value_type(*r++) can work. In this case, *r is the same as
+ // *r++, and the conversion operator below is used to ensure
+ // readability.
+ writable_postfix_increment_proxy const&
+ operator*() const
+ {
+ return *this;
+ }
+
+ // Provides readability of *r++
+ operator value_type&() const
+ {
+ return stored_value;
+ }
+
+ // Provides writability of *r++
+ template <class T>
+ T const& operator=(T const& x) const
+ {
+ *this->stored_iterator = x;
+ return x;
+ }
+
+ // This overload just in case only non-const objects are writable
+ template <class T>
+ T& operator=(T& x) const
+ {
+ *this->stored_iterator = x;
+ return x;
+ }
+
+ // Provides X(r++)
+ operator any_iterator_type const&() const
+ {
+ return stored_iterator;
+ }
+
+ private:
+ mutable value_type stored_value;
+ any_iterator_type stored_iterator;
+ };
+
+
+ }
+
+ namespace range_detail
+ {
+ template<
+ class Value
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ class any_iterator
+ : public iterator_facade<
+ any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ >
+ {
+ template<
+ class OtherValue
+ , class OtherTraversal
+ , class OtherReference
+ , class OtherDifference
+ , class OtherBuffer
+ >
+ friend class any_iterator;
+
+ struct enabler {};
+ struct disabler {};
+
+ typedef typename any_iterator_interface_type_generator<
+ Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type abstract_base_type;
+
+ typedef iterator_facade<
+ any_iterator<
+ Value
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >
+ , Value
+ , Traversal
+ , Reference
+ , Difference
+ > base_type;
+
+ typedef Buffer buffer_type;
+
+ public:
+ typedef typename base_type::value_type value_type;
+ typedef typename base_type::reference reference;
+ typedef typename base_type::difference_type difference_type;
+
+ // Default constructor
+ any_iterator()
+ : m_impl(0) {}
+
+ // Simple copy construction without conversion
+ any_iterator(const any_iterator& other)
+ : base_type(other)
+ , m_impl(other.m_impl
+ ? other.m_impl->clone(m_buffer)
+ : 0)
+ {
+ }
+
+ // Simple assignment operator without conversion
+ any_iterator& operator=(const any_iterator& other)
+ {
+ if (this != &other)
+ {
+ if (m_impl)
+ m_impl->~abstract_base_type();
+ m_buffer.deallocate();
+ m_impl = 0;
+ if (other.m_impl)
+ m_impl = other.m_impl->clone(m_buffer);
+ }
+ return *this;
+ }
+
+ // Implicit conversion from another any_iterator where the
+ // conversion is from a non-const reference to a const reference
+ template<
+ class OtherValue
+ , class OtherTraversal
+ , class OtherReference
+ , class OtherDifference
+ >
+ any_iterator(const any_iterator<
+ OtherValue,
+ OtherTraversal,
+ OtherReference,
+ OtherDifference,
+ Buffer
+ >& other,
+ typename enable_if<
+ typename mpl::and_<
+ typename is_mutable_reference<OtherReference>::type,
+ typename is_const_reference<Reference>::type
+ >::type,
+ enabler
+ >::type* = 0
+ )
+ : m_impl(other.m_impl
+ ? other.m_impl->clone_const_ref(m_buffer)
+ : 0
+ )
+ {
+ }
+
+ // Implicit conversion from another any_iterator where the
+ // reference types of the source and the target are references
+ // that are either both const, or both non-const.
+ template<
+ class OtherValue
+ , class OtherTraversal
+ , class OtherReference
+ , class OtherDifference
+ >
+ any_iterator(const any_iterator<
+ OtherValue
+ , OtherTraversal
+ , OtherReference
+ , OtherDifference
+ , Buffer
+ >& other,
+ typename enable_if<
+ typename mpl::or_<
+ typename mpl::and_<
+ typename is_mutable_reference<OtherReference>::type,
+ typename is_mutable_reference<Reference>::type
+ >::type,
+ typename mpl::and_<
+ typename is_const_reference<OtherReference>::type,
+ typename is_const_reference<Reference>::type
+ >::type
+ >::type,
+ enabler
+ >::type* = 0
+ )
+ : m_impl(other.m_impl
+ ? other.m_impl->clone(m_buffer)
+ : 0
+ )
+ {
+ }
+
+ // Implicit conversion to an any_iterator that uses a value for
+ // the reference type.
+ template<
+ class OtherValue
+ , class OtherTraversal
+ , class OtherReference
+ , class OtherDifference
+ >
+ any_iterator(const any_iterator<
+ OtherValue
+ , OtherTraversal
+ , OtherReference
+ , OtherDifference
+ , Buffer
+ >& other,
+ typename enable_if<
+ typename is_convertible_to_value_as_reference<
+ OtherReference
+ , Reference
+ >::type,
+ enabler
+ >::type* = 0
+ )
+ : m_impl(other.m_impl
+ ? other.m_impl->clone_reference_as_value(m_buffer)
+ : 0
+ )
+ {
+ }
+
+ any_iterator clone() const
+ {
+ any_iterator result;
+ if (m_impl)
+ result.m_impl = m_impl->clone(result.m_buffer);
+ return result;
+ }
+
+ any_iterator<
+ Value
+ , Traversal
+ , typename abstract_base_type::const_reference
+ , Difference
+ , Buffer
+ >
+ clone_const_ref() const
+ {
+ typedef any_iterator<
+ Value
+ , Traversal
+ , typename abstract_base_type::const_reference
+ , Difference
+ , Buffer
+ > result_type;
+
+ result_type result;
+
+ if (m_impl)
+ result.m_impl = m_impl->clone_const_ref(result.m_buffer);
+
+ return result;
+ }
+
+ // implicit conversion and construction from type-erasure-compatible
+ // iterators
+ template<class WrappedIterator>
+ explicit any_iterator(
+ const WrappedIterator& wrapped_iterator,
+ typename disable_if<
+ typename is_any_iterator<WrappedIterator>::type
+ , disabler
+ >::type* = 0
+ )
+ {
+ typedef typename any_iterator_wrapper_type_generator<
+ WrappedIterator
+ , Traversal
+ , Reference
+ , Difference
+ , Buffer
+ >::type wrapper_type;
+
+ void* ptr = m_buffer.allocate(sizeof(wrapper_type));
+ m_impl = new(ptr) wrapper_type(wrapped_iterator);
+ }
+
+ ~any_iterator()
+ {
+ // manually run the destructor, the deallocation is automatically
+ // handled by the any_iterator_small_buffer base class.
+ if (m_impl)
+ m_impl->~abstract_base_type();
+ }
+
+ private:
+ friend class ::boost::iterator_core_access;
+
+ Reference dereference() const
+ {
+ BOOST_ASSERT( m_impl );
+ return m_impl->dereference();
+ }
+
+ bool equal(const any_iterator& other) const
+ {
+ return (m_impl == other.m_impl)
+ || (m_impl && other.m_impl && m_impl->equal(*other.m_impl));
+ }
+
+ void increment()
+ {
+ BOOST_ASSERT( m_impl );
+ m_impl->increment();
+ }
+
+ void decrement()
+ {
+ BOOST_ASSERT( m_impl );
+ m_impl->decrement();
+ }
+
+ Difference distance_to(const any_iterator& other) const
+ {
+ return m_impl && other.m_impl
+ ? m_impl->distance_to(*other.m_impl)
+ : 0;
+ }
+
+ void advance(Difference offset)
+ {
+ BOOST_ASSERT( m_impl );
+ m_impl->advance(offset);
+ }
+
+ any_iterator& swap(any_iterator& other)
+ {
+ BOOST_ASSERT( this != &other );
+ // grab a temporary copy of the other iterator
+ any_iterator tmp(other);
+
+ // deallocate the other iterator, taking care to obey the
+ // class-invariants in-case of exceptions later
+ if (other.m_impl)
+ {
+ other.m_impl->~abstract_base_type();
+ other.m_buffer.deallocate();
+ other.m_impl = 0;
+ }
+
+ // If this is a non-null iterator then we need to put
+ // a clone of this iterators impementation into the other
+ // iterator.
+ // We can't just swap because of the small buffer optimization.
+ if (m_impl)
+ {
+ other.m_impl = m_impl->clone(other.m_buffer);
+ m_impl->~abstract_base_type();
+ m_buffer.deallocate();
+ m_impl = 0;
+ }
+
+ // assign to this instance a clone of the temporarily held
+ // tmp which represents the input other parameter at the
+ // start of execution of this function.
+ if (tmp.m_impl)
+ m_impl = tmp.m_impl->clone(m_buffer);
+
+ return *this;
+ }
+
+ buffer_type m_buffer;
+ abstract_base_type* m_impl;
+ };
+
+ } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/detail/any_iterator_buffer.hpp b/src/boost/range/detail/any_iterator_buffer.hpp
new file mode 100644
index 0000000..2bb5d53
--- /dev/null
+++ b/src/boost/range/detail/any_iterator_buffer.hpp
@@ -0,0 +1,117 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED
+
+#include <boost/array.hpp>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace boost
+{
+ template<std::size_t StackBufferSize>
+ class any_iterator_buffer
+ : noncopyable
+ {
+ BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
+ public:
+ any_iterator_buffer()
+ : m_ptr()
+ {
+ }
+
+ ~any_iterator_buffer()
+ {
+ delete [] m_ptr;
+ }
+
+ void* allocate(std::size_t bytes)
+ {
+ BOOST_ASSERT( !m_ptr );
+ if (bytes <= StackBufferSize)
+ return m_buffer.data();
+
+ m_ptr = new char[bytes];
+ return m_ptr;
+ }
+
+ void deallocate()
+ {
+ delete [] m_ptr;
+ m_ptr = 0;
+ }
+
+ private:
+ // Rationale:
+ // Do not use inheritance from noncopyable because this causes
+ // the concepts to erroneous detect the derived any_iterator
+ // as noncopyable.
+ any_iterator_buffer(const any_iterator_buffer&);
+ void operator=(const any_iterator_buffer&);
+
+ char* m_ptr;
+ boost::array<char, StackBufferSize> m_buffer;
+ };
+
+ class any_iterator_heap_only_buffer
+ : noncopyable
+ {
+ public:
+ any_iterator_heap_only_buffer()
+ : m_ptr()
+ {
+ }
+
+ ~any_iterator_heap_only_buffer()
+ {
+ delete [] m_ptr;
+ }
+
+ void* allocate(std::size_t bytes)
+ {
+ BOOST_ASSERT( !m_ptr );
+ m_ptr = new char[bytes];
+ return m_ptr;
+ }
+
+ void deallocate()
+ {
+ delete [] m_ptr;
+ m_ptr = 0;
+ }
+
+ private:
+ char* m_ptr;
+ };
+
+ template<std::size_t StackBufferSize>
+ class any_iterator_stack_only_buffer
+ {
+ BOOST_STATIC_ASSERT(( StackBufferSize > 0 ));
+ public:
+ void* allocate(std::size_t bytes)
+ {
+ BOOST_ASSERT( bytes <= m_buffer.size() );
+ return m_buffer.data();
+ }
+
+ void deallocate()
+ {
+ }
+
+ private:
+ boost::array<char, StackBufferSize> m_buffer;
+ };
+
+ typedef any_iterator_buffer<64> any_iterator_default_buffer;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/detail/any_iterator_interface.hpp b/src/boost/range/detail/any_iterator_interface.hpp
new file mode 100644
index 0000000..d8f4de7
--- /dev/null
+++ b/src/boost/range/detail/any_iterator_interface.hpp
@@ -0,0 +1,258 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED
+
+#include <boost/range/detail/any_iterator_buffer.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/add_const.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template<class T>
+ struct const_reference_type_generator
+ {
+ typedef typename mpl::if_<
+ typename is_reference<T>::type,
+ typename add_reference<
+ typename add_const<
+ typename remove_reference<T>::type
+ >::type
+ >::type,
+ T
+ >::type type;
+ };
+
+ template<
+ class Reference
+ , class Buffer
+ >
+ struct any_incrementable_iterator_interface
+ {
+ typedef Reference reference;
+ typedef typename const_reference_type_generator<
+ Reference
+ >::type const_reference;
+ typedef typename remove_const<
+ typename remove_reference<Reference>::type
+ >::type reference_as_value_type;
+
+ typedef Buffer buffer_type;
+
+ virtual ~any_incrementable_iterator_interface() {}
+
+ virtual any_incrementable_iterator_interface*
+ clone(buffer_type& buffer) const = 0;
+
+ virtual any_incrementable_iterator_interface<const_reference, Buffer>*
+ clone_const_ref(buffer_type& buffer) const = 0;
+
+ virtual any_incrementable_iterator_interface<reference_as_value_type, Buffer>*
+ clone_reference_as_value(buffer_type& buffer) const = 0;
+
+ virtual void increment() = 0;
+ };
+
+ template<
+ class Reference
+ , class Buffer
+ >
+ struct any_single_pass_iterator_interface
+ : any_incrementable_iterator_interface<Reference, Buffer>
+ {
+ typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference reference;
+ typedef typename any_incrementable_iterator_interface<Reference, Buffer>::const_reference const_reference;
+ typedef typename any_incrementable_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
+ typedef typename any_incrementable_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
+
+ virtual any_single_pass_iterator_interface*
+ clone(buffer_type& buffer) const = 0;
+
+ virtual any_single_pass_iterator_interface<const_reference, Buffer>*
+ clone_const_ref(buffer_type& buffer) const = 0;
+
+ virtual any_single_pass_iterator_interface<reference_as_value_type, Buffer>*
+ clone_reference_as_value(buffer_type& buffer) const = 0;
+
+ virtual Reference dereference() const = 0;
+
+ virtual bool equal(const any_single_pass_iterator_interface& other) const = 0;
+ };
+
+ template<
+ class Reference
+ , class Buffer
+ >
+ struct any_forward_iterator_interface
+ : any_single_pass_iterator_interface<Reference, Buffer>
+ {
+ typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference reference;
+ typedef typename any_single_pass_iterator_interface<Reference, Buffer>::const_reference const_reference;
+ typedef typename any_single_pass_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
+ typedef typename any_single_pass_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
+
+ virtual any_forward_iterator_interface*
+ clone(buffer_type& buffer) const = 0;
+
+ virtual any_forward_iterator_interface<const_reference, Buffer>*
+ clone_const_ref(buffer_type& buffer) const = 0;
+
+ virtual any_forward_iterator_interface<reference_as_value_type, Buffer>*
+ clone_reference_as_value(buffer_type& buffer) const = 0;
+ };
+
+ template<
+ class Reference
+ , class Buffer
+ >
+ struct any_bidirectional_iterator_interface
+ : any_forward_iterator_interface<Reference, Buffer>
+ {
+ typedef typename any_forward_iterator_interface<Reference, Buffer>::reference reference;
+ typedef typename any_forward_iterator_interface<Reference, Buffer>::const_reference const_reference;
+ typedef typename any_forward_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
+ typedef typename any_forward_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
+
+ virtual any_bidirectional_iterator_interface*
+ clone(buffer_type& buffer) const = 0;
+
+ virtual any_bidirectional_iterator_interface<const_reference, Buffer>*
+ clone_const_ref(buffer_type& buffer) const = 0;
+
+ virtual any_bidirectional_iterator_interface<reference_as_value_type, Buffer>*
+ clone_reference_as_value(buffer_type& buffer) const = 0;
+
+ virtual void decrement() = 0;
+ };
+
+ template<
+ class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_random_access_iterator_interface
+ : any_bidirectional_iterator_interface<
+ Reference
+ , Buffer
+ >
+ {
+ typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference reference;
+ typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::const_reference const_reference;
+ typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::buffer_type buffer_type;
+ typedef typename any_bidirectional_iterator_interface<Reference, Buffer>::reference_as_value_type reference_as_value_type;
+ typedef Difference difference_type;
+
+ virtual any_random_access_iterator_interface*
+ clone(buffer_type& buffer) const = 0;
+
+ virtual any_random_access_iterator_interface<const_reference, Difference, Buffer>*
+ clone_const_ref(buffer_type& buffer) const = 0;
+
+ virtual any_random_access_iterator_interface<reference_as_value_type, Difference, Buffer>*
+ clone_reference_as_value(buffer_type& buffer) const = 0;
+
+ virtual void advance(Difference offset) = 0;
+
+ virtual Difference distance_to(const any_random_access_iterator_interface& other) const = 0;
+ };
+
+ template<
+ class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_interface_type_generator;
+
+ template<
+ class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_interface_type_generator<
+ incrementable_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_incrementable_iterator_interface<Reference, Buffer> type;
+ };
+
+ template<
+ class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_interface_type_generator<
+ single_pass_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_single_pass_iterator_interface<Reference, Buffer> type;
+ };
+
+ template<
+ class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_interface_type_generator<
+ forward_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_forward_iterator_interface<Reference, Buffer> type;
+ };
+
+ template<
+ class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_interface_type_generator<
+ bidirectional_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_bidirectional_iterator_interface<Reference, Buffer> type;
+ };
+
+ template<
+ class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_interface_type_generator<
+ random_access_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_random_access_iterator_interface<
+ Reference
+ , Difference
+ , Buffer
+ > type;
+ };
+
+ } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/detail/any_iterator_wrapper.hpp b/src/boost/range/detail/any_iterator_wrapper.hpp
new file mode 100644
index 0000000..b5313a7
--- /dev/null
+++ b/src/boost/range/detail/any_iterator_wrapper.hpp
@@ -0,0 +1,590 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED
+
+#include <boost/range/config.hpp>
+#include <boost/range/detail/any_iterator_interface.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Buffer
+ >
+ class any_incrementable_iterator_wrapper
+ : public any_incrementable_iterator_interface<
+ Reference
+ , Buffer
+ >
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( IncrementableIteratorConcept<WrappedIterator> ));
+ public:
+ typedef WrappedIterator wrapped_type;
+
+ BOOST_STATIC_ASSERT(( is_convertible<
+ typename iterator_reference<WrappedIterator>::type
+ , Reference
+ >::value ));
+
+ any_incrementable_iterator_wrapper()
+ : m_it()
+ {}
+
+ explicit any_incrementable_iterator_wrapper(wrapped_type it)
+ : m_it(it)
+ {}
+
+ // any_incrementable_iterator implementation
+ virtual any_incrementable_iterator_wrapper* clone(
+ typename any_incrementable_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ return new (buffer.allocate(sizeof(*this)))
+ any_incrementable_iterator_wrapper(m_it);
+ }
+
+ virtual any_incrementable_iterator_wrapper<
+ WrappedIterator
+ , typename any_incrementable_iterator_wrapper::const_reference
+ , Buffer
+ >* clone_const_ref(
+ typename any_incrementable_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_incrementable_iterator_wrapper<
+ WrappedIterator
+ , typename any_incrementable_iterator_wrapper::const_reference
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual any_incrementable_iterator_wrapper<
+ WrappedIterator
+ , typename any_incrementable_iterator_wrapper::reference_as_value_type
+ , Buffer
+ >* clone_reference_as_value(
+ typename any_incrementable_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_incrementable_iterator_wrapper<
+ WrappedIterator
+ , typename any_incrementable_iterator_wrapper::reference_as_value_type
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual void increment()
+ {
+ ++m_it;
+ }
+
+ private:
+ wrapped_type m_it;
+ };
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Buffer
+ >
+ class any_single_pass_iterator_wrapper
+ : public any_single_pass_iterator_interface<
+ Reference
+ , Buffer
+ >
+ {
+ struct disabler {};
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept<WrappedIterator> ));
+ public:
+
+ any_single_pass_iterator_wrapper()
+ : m_it()
+ {}
+
+ explicit any_single_pass_iterator_wrapper(const WrappedIterator& it)
+ : m_it(it)
+ {}
+ // any_single_pass_iterator_interface<Reference> implementation
+ virtual any_single_pass_iterator_wrapper* clone(
+ typename any_single_pass_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ return new (buffer.allocate(sizeof(*this)))
+ any_single_pass_iterator_wrapper(m_it);
+ }
+
+ virtual any_single_pass_iterator_wrapper<
+ WrappedIterator
+ , typename any_single_pass_iterator_wrapper::const_reference
+ , Buffer
+ >* clone_const_ref(
+ typename any_single_pass_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_single_pass_iterator_wrapper<
+ WrappedIterator
+ , typename any_single_pass_iterator_wrapper::const_reference
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual any_single_pass_iterator_wrapper<
+ WrappedIterator
+ , typename any_single_pass_iterator_wrapper::reference_as_value_type
+ , Buffer
+ >* clone_reference_as_value(
+ typename any_single_pass_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_single_pass_iterator_wrapper<
+ WrappedIterator
+ , typename any_single_pass_iterator_wrapper::reference_as_value_type
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual void increment()
+ {
+ ++m_it;
+ }
+
+ virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
+ {
+ return m_it == boost::polymorphic_downcast<const any_single_pass_iterator_wrapper*>(&other)->m_it;
+ }
+
+ virtual Reference dereference() const
+ {
+ return *m_it;
+ }
+
+ private:
+ WrappedIterator m_it;
+ };
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Buffer
+ >
+ class any_forward_iterator_wrapper
+ : public any_forward_iterator_interface<
+ Reference
+ , Buffer
+ >
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept<WrappedIterator> ));
+ public:
+ any_forward_iterator_wrapper()
+ : m_it()
+ {}
+
+ explicit any_forward_iterator_wrapper(const WrappedIterator& it)
+ : m_it(it)
+ {}
+
+ // any_forward_iterator_interface<Reference> implementation
+ virtual any_forward_iterator_wrapper* clone(
+ typename any_forward_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ return new (buffer.allocate(sizeof(*this)))
+ any_forward_iterator_wrapper(m_it);
+ }
+
+ virtual any_forward_iterator_wrapper<
+ WrappedIterator
+ , typename any_forward_iterator_wrapper::const_reference
+ , Buffer
+ >* clone_const_ref(
+ typename any_forward_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_forward_iterator_wrapper<
+ WrappedIterator
+ , typename any_forward_iterator_wrapper::const_reference
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual any_forward_iterator_wrapper<
+ WrappedIterator
+ , typename any_forward_iterator_wrapper::reference_as_value_type
+ , Buffer
+ >* clone_reference_as_value(
+ typename any_forward_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_forward_iterator_wrapper<
+ WrappedIterator
+ , typename any_forward_iterator_wrapper::reference_as_value_type
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual void increment()
+ {
+ ++m_it;
+ }
+
+ virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
+ {
+ return m_it == boost::polymorphic_downcast<const any_forward_iterator_wrapper*>(&other)->m_it;
+ }
+
+ virtual Reference dereference() const
+ {
+ return *m_it;
+ }
+ private:
+ WrappedIterator m_it;
+ };
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Buffer
+ >
+ class any_bidirectional_iterator_wrapper
+ : public any_bidirectional_iterator_interface<
+ Reference
+ , Buffer
+ >
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept<WrappedIterator> ));
+ public:
+ any_bidirectional_iterator_wrapper()
+ : m_it()
+ {
+ }
+
+ explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it)
+ : m_it(it)
+ {
+ }
+
+ virtual any_bidirectional_iterator_wrapper* clone(
+ typename any_bidirectional_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ return new (buffer.allocate(sizeof(*this)))
+ any_bidirectional_iterator_wrapper(*this);
+ }
+
+ virtual any_bidirectional_iterator_wrapper<
+ WrappedIterator
+ , typename any_bidirectional_iterator_wrapper::const_reference
+ , Buffer
+ >* clone_const_ref(
+ typename any_bidirectional_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_bidirectional_iterator_wrapper<
+ WrappedIterator
+ , typename any_bidirectional_iterator_wrapper::const_reference
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual any_bidirectional_iterator_wrapper<
+ WrappedIterator
+ , typename any_bidirectional_iterator_wrapper::reference_as_value_type
+ , Buffer
+ >* clone_reference_as_value(
+ typename any_bidirectional_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_bidirectional_iterator_wrapper<
+ WrappedIterator
+ , typename any_bidirectional_iterator_wrapper::reference_as_value_type
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual void increment()
+ {
+ ++m_it;
+ }
+
+ virtual void decrement()
+ {
+ --m_it;
+ }
+
+ virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
+ {
+ return m_it == boost::polymorphic_downcast<const any_bidirectional_iterator_wrapper*>(&other)->m_it;
+ }
+
+ virtual Reference dereference() const
+ {
+ return *m_it;
+ }
+
+ private:
+ WrappedIterator m_it;
+ };
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ class any_random_access_iterator_wrapper
+ : public any_random_access_iterator_interface<
+ Reference
+ , Difference
+ , Buffer
+ >
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept<WrappedIterator> ));
+ public:
+ typedef Difference difference_type;
+
+ any_random_access_iterator_wrapper()
+ : m_it()
+ {
+ }
+
+ explicit any_random_access_iterator_wrapper(const WrappedIterator& other)
+ : m_it(other)
+ {
+ }
+
+ virtual any_random_access_iterator_wrapper* clone(
+ typename any_random_access_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ return new (buffer.allocate(sizeof(*this)))
+ any_random_access_iterator_wrapper(*this);
+ }
+
+ virtual any_random_access_iterator_wrapper<
+ WrappedIterator
+ , typename any_random_access_iterator_wrapper::const_reference
+ , Difference
+ , Buffer
+ >* clone_const_ref(
+ typename any_random_access_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_random_access_iterator_wrapper<
+ WrappedIterator
+ , typename any_random_access_iterator_wrapper::const_reference
+ , Difference
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual any_random_access_iterator_wrapper<
+ WrappedIterator
+ , typename any_random_access_iterator_wrapper::reference_as_value_type
+ , Difference
+ , Buffer
+ >* clone_reference_as_value(
+ typename any_random_access_iterator_wrapper::buffer_type& buffer
+ ) const
+ {
+ typedef any_random_access_iterator_wrapper<
+ WrappedIterator
+ , typename any_random_access_iterator_wrapper::reference_as_value_type
+ , Difference
+ , Buffer
+ > result_type;
+
+ return new (buffer.allocate(sizeof(result_type)))
+ result_type(m_it);
+ }
+
+ virtual void increment()
+ {
+ ++m_it;
+ }
+
+ virtual bool equal(const any_single_pass_iterator_interface<Reference, Buffer>& other) const
+ {
+ return m_it == boost::polymorphic_downcast<const any_random_access_iterator_wrapper*>(&other)->m_it;
+ }
+
+ virtual void decrement()
+ {
+ --m_it;
+ }
+
+ virtual void advance(Difference offset)
+ {
+ m_it += offset;
+ }
+
+ virtual Reference dereference() const
+ {
+ return *m_it;
+ }
+
+ virtual Difference distance_to(const any_random_access_iterator_interface<Reference, Difference, Buffer>& other) const
+ {
+ return boost::polymorphic_downcast<const any_random_access_iterator_wrapper*>(&other)->m_it - m_it;
+ }
+
+ private:
+ WrappedIterator m_it;
+ };
+
+ template<
+ class WrappedIterator
+ , class Traversal
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_wrapper_type_generator;
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_wrapper_type_generator<
+ WrappedIterator
+ , incrementable_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_incrementable_iterator_wrapper<
+ WrappedIterator
+ , Reference
+ , Buffer
+ > type;
+ };
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_wrapper_type_generator<
+ WrappedIterator
+ , single_pass_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_single_pass_iterator_wrapper<
+ WrappedIterator
+ , Reference
+ , Buffer
+ > type;
+ };
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_wrapper_type_generator<
+ WrappedIterator
+ , forward_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_forward_iterator_wrapper<
+ WrappedIterator
+ , Reference
+ , Buffer
+ > type;
+ };
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_wrapper_type_generator<
+ WrappedIterator
+ , bidirectional_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_bidirectional_iterator_wrapper<
+ WrappedIterator
+ , Reference
+ , Buffer
+ > type;
+ };
+
+ template<
+ class WrappedIterator
+ , class Reference
+ , class Difference
+ , class Buffer
+ >
+ struct any_iterator_wrapper_type_generator<
+ WrappedIterator
+ , random_access_traversal_tag
+ , Reference
+ , Difference
+ , Buffer
+ >
+ {
+ typedef any_random_access_iterator_wrapper<
+ WrappedIterator
+ , Reference
+ , Difference
+ , Buffer
+ > type;
+ };
+
+ } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/detail/as_literal.hpp b/src/boost/range/detail/as_literal.hpp
new file mode 100644
index 0000000..0bd9a15
--- /dev/null
+++ b/src/boost/range/detail/as_literal.hpp
@@ -0,0 +1,33 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_AS_LITERAL_HPP
+#define BOOST_RANGE_DETAIL_AS_LITERAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/detail/detail_str.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+ template< class Range >
+ inline iterator_range<BOOST_DEDUCED_TYPENAME range_iterator<Range>::type>
+ as_literal( Range& r )
+ {
+ return ::boost::make_iterator_range( ::boost::range_detail::str_begin(r),
+ ::boost::range_detail::str_end(r) );
+ }
+
+}
+
+#endif
diff --git a/src/boost/range/detail/begin.hpp b/src/boost/range/detail/begin.hpp
new file mode 100644
index 0000000..f3da732
--- /dev/null
+++ b/src/boost/range/detail/begin.hpp
@@ -0,0 +1,94 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_BEGIN_HPP
+#define BOOST_RANGE_DETAIL_BEGIN_HPP
+
+#include <boost/config.hpp> // BOOST_MSVC
+#include <boost/detail/workaround.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/detail/common.hpp>
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1310)
+# include <boost/range/value_type.hpp>
+#endif
+
+namespace boost
+{
+
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_begin;
+
+ //////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_begin<std_container_>
+ {
+ template< typename C >
+ static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type fun( C& c )
+ {
+ return c.begin();
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_begin<std_pair_>
+ {
+ template< typename P >
+ static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type fun( const P& p )
+ {
+ return p.first;
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_begin<array_>
+ {
+ #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
+ template< typename T, std::size_t sz >
+ static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return boost_range_array;
+ }
+ #else
+ template<typename T>
+ static BOOST_RANGE_DEDUCED_TYPENAME range_value<T>::type* fun(T& t)
+ {
+ return t;
+ }
+ #endif
+ };
+
+ } // namespace 'range_detail'
+
+ namespace range_adl_barrier
+ {
+ template< typename C >
+ inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
+ begin( C& c )
+ {
+ return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
+ }
+ }
+} // namespace 'boost'
+
+
+#endif
diff --git a/src/boost/range/detail/collection_traits.hpp b/src/boost/range/detail/collection_traits.hpp
new file mode 100644
index 0000000..c50ca3e
--- /dev/null
+++ b/src/boost/range/detail/collection_traits.hpp
@@ -0,0 +1,266 @@
+// Boost string_algo library collection_traits.hpp header file -------------//
+
+// Copyright Pavol Droba 2002-2003. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// (C) Copyright Thorsten Ottosen 2002-2003. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// (C) Copyright Jeremy Siek 2001. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Original idea of container traits was proposed by Jeremy Siek and
+// Thorsten Ottosen. This implementation is lightweighted version
+// of container_traits adapter for usage with string_algo library
+
+#ifndef BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP
+#define BOOST_RANGE_STRING_COLLECTION_TRAITS_HPP
+
+#include <boost/algorithm/string/config.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/mpl/eval_if.hpp>
+
+// Implementation
+#include <boost/range/detail/collection_traits_detail.hpp>
+
+/*! \file
+ Defines collection_traits class and related free-standing functions.
+ This facility is used to unify the access to different types of collections.
+ It allows the algorithms in the library to work with STL collections, c-style
+ array, null-terminated c-strings (and more) using the same interface.
+*/
+
+namespace boost {
+ namespace algorithm {
+
+// collection_traits template class -----------------------------------------//
+
+ //! collection_traits class
+ /*!
+ Collection traits provide uniform access to different types of
+ collections. This functionality allows to write generic algorithms
+ which work with several different kinds of collections.
+
+ Currently following collection types are supported:
+ - containers with STL compatible container interface ( see ContainerConcept )
+ ( i.e. \c std::vector<>, \c std::list<>, \c std::string<> ... )
+ - c-style array
+ ( \c char[10], \c int[15] ... )
+ - null-terminated c-strings
+ ( \c char*, \c wchar_T* )
+ - std::pair of iterators
+ ( i.e \c std::pair<vector<int>::iterator,vector<int>::iterator> )
+
+ Collection traits provide an external collection interface operations.
+ All are accessible using free-standing functions.
+
+ The following operations are supported:
+ - \c size()
+ - \c empty()
+ - \c begin()
+ - \c end()
+
+ Container traits have somewhat limited functionality on compilers not
+ supporting partial template specialization and partial template ordering.
+ */
+ template< typename T >
+ struct collection_traits
+ {
+ private:
+ typedef BOOST_STRING_TYPENAME ::boost::mpl::eval_if<
+ ::boost::algorithm::detail::is_pair<T>,
+ detail::pair_container_traits_selector<T>,
+ BOOST_STRING_TYPENAME ::boost::mpl::eval_if<
+ ::boost::is_array<T>,
+ detail::array_container_traits_selector<T>,
+ BOOST_STRING_TYPENAME ::boost::mpl::eval_if<
+ ::boost::is_pointer<T>,
+ detail::pointer_container_traits_selector<T>,
+ detail::default_container_traits_selector<T>
+ >
+ >
+ >::type container_helper_type;
+ public:
+ //! Function type
+ typedef container_helper_type function_type;
+ //! Value type
+ typedef BOOST_STRING_TYPENAME
+ container_helper_type::value_type value_type;
+ //! Size type
+ typedef BOOST_STRING_TYPENAME
+ container_helper_type::size_type size_type;
+ //! Iterator type
+ typedef BOOST_STRING_TYPENAME
+ container_helper_type::iterator iterator;
+ //! Const iterator type
+ typedef BOOST_STRING_TYPENAME
+ container_helper_type::const_iterator const_iterator;
+ //! Result iterator type ( iterator of const_iterator, depending on the constness of the container )
+ typedef BOOST_STRING_TYPENAME
+ container_helper_type::result_iterator result_iterator;
+ //! Difference type
+ typedef BOOST_STRING_TYPENAME
+ container_helper_type::difference_type difference_type;
+
+ }; // 'collection_traits'
+
+// collection_traits metafunctions -----------------------------------------//
+
+ //! Container value_type trait
+ /*!
+ Extract the type of elements contained in a container
+ */
+ template< typename C >
+ struct value_type_of
+ {
+ typedef BOOST_STRING_TYPENAME collection_traits<C>::value_type type;
+ };
+
+ //! Container difference trait
+ /*!
+ Extract the container's difference type
+ */
+ template< typename C >
+ struct difference_type_of
+ {
+ typedef BOOST_STRING_TYPENAME collection_traits<C>::difference_type type;
+ };
+
+ //! Container iterator trait
+ /*!
+ Extract the container's iterator type
+ */
+ template< typename C >
+ struct iterator_of
+ {
+ typedef BOOST_STRING_TYPENAME collection_traits<C>::iterator type;
+ };
+
+ //! Container const_iterator trait
+ /*!
+ Extract the container's const_iterator type
+ */
+ template< typename C >
+ struct const_iterator_of
+ {
+ typedef BOOST_STRING_TYPENAME collection_traits<C>::const_iterator type;
+ };
+
+
+ //! Container result_iterator
+ /*!
+ Extract the container's result_iterator type. This type maps to \c C::iterator
+ for mutable container and \c C::const_iterator for const containers.
+ */
+ template< typename C >
+ struct result_iterator_of
+ {
+ typedef BOOST_STRING_TYPENAME collection_traits<C>::result_iterator type;
+ };
+
+// collection_traits related functions -----------------------------------------//
+
+ //! Free-standing size() function
+ /*!
+ Get the size of the container. Uses collection_traits.
+ */
+ template< typename C >
+ inline BOOST_STRING_TYPENAME collection_traits<C>::size_type
+ size( const C& c )
+ {
+ return collection_traits<C>::function_type::size( c );
+ }
+
+ //! Free-standing empty() function
+ /*!
+ Check whether the container is empty. Uses container traits.
+ */
+ template< typename C >
+ inline bool empty( const C& c )
+ {
+ return collection_traits<C>::function_type::empty( c );
+ }
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ //! Free-standing begin() function
+ /*!
+ Get the begin iterator of the container. Uses collection_traits.
+ */
+ template< typename C >
+ inline BOOST_STRING_TYPENAME collection_traits<C>::iterator
+ begin( C& c )
+ {
+ return collection_traits<C>::function_type::begin( c );
+ }
+
+ //! Free-standing begin() function
+ /*!
+ \overload
+ */
+ template< typename C >
+ inline BOOST_STRING_TYPENAME collection_traits<C>::const_iterator
+ begin( const C& c )
+ {
+ return collection_traits<C>::function_type::begin( c );
+ }
+
+ //! Free-standing end() function
+ /*!
+ Get the begin iterator of the container. Uses collection_traits.
+ */
+ template< typename C >
+ inline BOOST_STRING_TYPENAME collection_traits<C>::iterator
+ end( C& c )
+ {
+ return collection_traits<C>::function_type::end( c );
+ }
+
+ //! Free-standing end() function
+ /*!
+ \overload
+ */
+ template< typename C >
+ inline BOOST_STRING_TYPENAME collection_traits<C>::const_iterator
+ end( const C& c )
+ {
+ return collection_traits<C>::function_type::end( c );
+ }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ //! Free-standing begin() function
+ /*!
+ \overload
+ */
+ template< typename C >
+ inline BOOST_STRING_TYPENAME collection_traits<C>::result_iterator
+ begin( C& c )
+ {
+ return collection_traits<C>::function_type::begin( c );
+ }
+
+ //! Free-standing end() function
+ /*!
+ \overload
+ */
+ template< typename C >
+ inline BOOST_STRING_TYPENAME collection_traits<C>::result_iterator
+ end( C& c )
+ {
+ return collection_traits<C>::function_type::end( c );
+ }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ } // namespace algorithm
+} // namespace boost
+
+#endif // BOOST_STRING_COLLECTION_TRAITS_HPP
diff --git a/src/boost/range/detail/collection_traits_detail.hpp b/src/boost/range/detail/collection_traits_detail.hpp
new file mode 100644
index 0000000..44fbde0
--- /dev/null
+++ b/src/boost/range/detail/collection_traits_detail.hpp
@@ -0,0 +1,621 @@
+// Boost string_algo library collection_traits.hpp header file -----------------------//
+
+// Copyright Pavol Droba 2002-2003. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
+#define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
+
+#include <boost/algorithm/string/config.hpp>
+#include <cstddef>
+#include <string>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/algorithm/string/yes_no_type.hpp>
+
+// Container traits implementation ---------------------------------------------------------
+
+namespace boost {
+ namespace algorithm {
+ namespace detail {
+
+// Default collection traits -----------------------------------------------------------------
+
+ // Default collection helper
+ /*
+ Wraps std::container compliant containers
+ */
+ template< typename ContainerT >
+ struct default_container_traits
+ {
+ typedef BOOST_STRING_TYPENAME ContainerT::value_type value_type;
+ typedef BOOST_STRING_TYPENAME ContainerT::iterator iterator;
+ typedef BOOST_STRING_TYPENAME ContainerT::const_iterator const_iterator;
+ typedef BOOST_STRING_TYPENAME
+ ::boost::mpl::if_< ::boost::is_const<ContainerT>,
+ const_iterator,
+ iterator
+ >::type result_iterator;
+ typedef BOOST_STRING_TYPENAME ContainerT::difference_type difference_type;
+ typedef BOOST_STRING_TYPENAME ContainerT::size_type size_type;
+
+ // static operations
+ template< typename C >
+ static size_type size( const C& c )
+ {
+ return c.size();
+ }
+
+ template< typename C >
+ static bool empty( const C& c )
+ {
+ return c.empty();
+ }
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< typename C >
+ static iterator begin( C& c )
+ {
+ return c.begin();
+ }
+
+ template< typename C >
+ static const_iterator begin( const C& c )
+ {
+ return c.begin();
+ }
+
+ template< typename C >
+ static iterator end( C& c )
+ {
+ return c.end();
+ }
+
+ template< typename C >
+ static const_iterator end( const C& c )
+ {
+ return c.end();
+ }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< typename C >
+ static result_iterator begin( C& c )
+ {
+ return c.begin();
+ }
+
+ template< typename C >
+ static result_iterator end( C& c )
+ {
+ return c.end();
+ }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ };
+
+ template<typename T>
+ struct default_container_traits_selector
+ {
+ typedef default_container_traits<T> type;
+ };
+
+// Pair container traits ---------------------------------------------------------------------
+
+ // pair selector
+ template< typename T, typename U >
+ yes_type is_pair_impl( const std::pair<T,U>* );
+ no_type is_pair_impl( ... );
+
+ template<typename T> struct is_pair
+ {
+ private:
+ static T* t;
+ public:
+ BOOST_STATIC_CONSTANT( bool, value=
+ sizeof(is_pair_impl(t))==sizeof(yes_type) );
+ };
+
+ // pair helper
+ template< typename PairT >
+ struct pair_container_traits
+ {
+ typedef BOOST_STRING_TYPENAME PairT::first_type element_type;
+
+ typedef BOOST_STRING_TYPENAME ::boost::detail::
+ iterator_traits<element_type>::value_type value_type;
+ typedef std::size_t size_type;
+ typedef BOOST_STRING_TYPENAME ::boost::detail::
+ iterator_traits<element_type>::difference_type difference_type;
+
+ typedef element_type iterator;
+ typedef element_type const_iterator;
+ typedef element_type result_iterator;
+
+ // static operations
+ template< typename P >
+ static size_type size( const P& p )
+ {
+ difference_type diff = std::distance( p.first, p.second );
+ if ( diff < 0 )
+ return 0;
+ else
+ return diff;
+ }
+
+ template< typename P >
+ static bool empty( const P& p )
+ {
+ return p.first==p.second;
+ }
+
+ template< typename P >
+ static const_iterator begin( const P& p )
+ {
+ return p.first;
+ }
+
+ template< typename P >
+ static const_iterator end( const P& p )
+ {
+ return p.second;
+ }
+ }; // 'pair_container_helper'
+
+ template<typename T>
+ struct pair_container_traits_selector
+ {
+ typedef pair_container_traits<T> type;
+ };
+
+// Array container traits ---------------------------------------------------------------
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ // array traits ( partial specialization )
+ template< typename T >
+ struct array_traits;
+
+ template< typename T, std::size_t sz >
+ struct array_traits<T[sz]>
+ {
+ // typedef
+ typedef T* iterator;
+ typedef const T* const_iterator;
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ // size of the array ( static );
+ BOOST_STATIC_CONSTANT( size_type, array_size = sz );
+ };
+
+#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+ // array traits ( no partial specialization )
+ /*
+ without parial specialization we are able to
+ provide support only for a limited number of
+ types. Currently the primitive numeric types
+ are supported
+ */
+ template< typename T, typename BaseT >
+ struct array_traits_impl
+ {
+ typedef BaseT value_type;
+ typedef BaseT* iterator;
+ typedef const BaseT* const_iterator;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ // size of the array
+ BOOST_STATIC_CONSTANT( size_type, array_size = sizeof(T)/sizeof(BaseT) );
+ };
+
+ template< typename T, typename BaseT >
+ struct array_traits_impl_selector
+ {
+ typedef array_traits_impl<T,BaseT> type;
+ };
+
+ struct array_traits_void
+ {
+ typedef void type;
+ };
+
+ template< typename T, typename BaseT >
+ struct array_traits_cv_selector
+ {
+ typedef BOOST_STRING_TYPENAME
+ ::boost::mpl::eval_if<
+ ::boost::is_convertible<T,BaseT*>,
+ array_traits_impl_selector<T,BaseT>,
+ ::boost::mpl::eval_if<
+ ::boost::is_convertible<T,const BaseT*>,
+ array_traits_impl_selector<T, const BaseT>,
+ ::boost::mpl::eval_if<
+ ::boost::is_convertible<T, volatile BaseT*>,
+ array_traits_impl_selector<T, volatile BaseT>,
+ array_traits_impl_selector<T, const volatile BaseT>
+ >
+ >
+ >::type type;
+ };
+
+ template< typename T >
+ struct array_traits_select
+ {
+ template< typename T1, typename T2 >
+ struct apply
+ {
+ typedef BOOST_STRING_TYPENAME
+ ::boost::mpl::eval_if<
+ ::boost::is_convertible<T,const volatile T2*>,
+ array_traits_cv_selector<T,T2>,
+ ::boost::mpl::identity<T1> >::type type;
+ };
+ };
+
+ template< typename T >
+ struct array_traits_selector
+ {
+ private:
+ // supported array base types
+#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+ typedef BOOST_STRING_TYPENAME
+ ::boost::mpl::vector10<
+ wchar_t,
+#else // BOOST_NO_INTRINSIC_WCHAR_T
+ typedef BOOST_STRING_TYPENAME
+ ::boost::mpl::vector9<
+#endif // BOOST_NO_INTRINSIC_WCHAR_T
+ char,
+ signed char,
+ unsigned char,
+ signed short,
+ unsigned short,
+ signed int,
+ unsigned int,
+ signed long,
+ unsigned long
+ >::type array_base_types;
+
+ public:
+ typedef BOOST_STRING_TYPENAME
+ ::boost::mpl::fold<
+ array_base_types,
+ ::boost::algorithm::detail::array_traits_void,
+ ::boost::algorithm::detail::array_traits_select<T> >::type type;
+ };
+
+ template< typename T >
+ struct array_traits
+ {
+ typedef BOOST_STRING_TYPENAME
+ array_traits_selector<T>::type traits_type;
+
+ typedef BOOST_STRING_TYPENAME
+ traits_type::value_type value_type;
+ typedef BOOST_STRING_TYPENAME
+ traits_type::iterator iterator;
+ typedef BOOST_STRING_TYPENAME
+ traits_type::const_iterator const_iterator;
+ typedef BOOST_STRING_TYPENAME
+ traits_type::size_type size_type;
+ typedef BOOST_STRING_TYPENAME
+ traits_type::difference_type difference_type;
+
+ BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
+ };
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+ // array lenght resolving
+ /*
+ Lenght of string contained in a static array could
+ be different from the size of the array.
+ For string processing we need the lenght without
+ terminating 0.
+
+ Therefore, the lenght is calulated for char and wchar_t
+ using char_traits, rather then simply returning
+ the array size.
+ */
+ template< typename T >
+ struct array_length_selector
+ {
+ template< typename TraitsT >
+ struct array_length
+ {
+ typedef BOOST_STRING_TYPENAME
+ TraitsT::size_type size_type;
+
+ BOOST_STATIC_CONSTANT(
+ size_type,
+ array_size=TraitsT::array_size );
+
+ template< typename A >
+ static size_type length( const A& )
+ {
+ return array_size;
+ }
+
+ template< typename A >
+ static bool empty( const A& )
+ {
+ return array_size==0;
+ }
+ };
+ };
+
+ // specialization for char
+ template<>
+ struct array_length_selector<char>
+ {
+ template< typename TraitsT >
+ struct array_length
+ {
+ typedef BOOST_STRING_TYPENAME
+ TraitsT::size_type size_type;
+
+ template< typename A >
+ static size_type length( const A& a )
+ {
+ if ( a==0 )
+ return 0;
+ else
+ return std::char_traits<char>::length(a);
+ }
+
+ template< typename A >
+ static bool empty( const A& a )
+ {
+ return a==0 || a[0]==0;
+ }
+ };
+ };
+
+ // specialization for wchar_t
+ template<>
+ struct array_length_selector<wchar_t>
+ {
+ template< typename TraitsT >
+ struct array_length
+ {
+ typedef BOOST_STRING_TYPENAME
+ TraitsT::size_type size_type;
+
+ template< typename A >
+ static size_type length( const A& a )
+ {
+ if ( a==0 )
+ return 0;
+ else
+ return std::char_traits<wchar_t>::length(a);
+ }
+
+ template< typename A >
+ static bool empty( const A& a )
+ {
+ return a==0 || a[0]==0;
+ }
+ };
+ };
+
+ template< typename T >
+ struct array_container_traits
+ {
+ private:
+ // resolve array traits
+ typedef array_traits<T> traits_type;
+
+ public:
+ typedef BOOST_STRING_TYPENAME
+ traits_type::value_type value_type;
+ typedef BOOST_STRING_TYPENAME
+ traits_type::iterator iterator;
+ typedef BOOST_STRING_TYPENAME
+ traits_type::const_iterator const_iterator;
+ typedef BOOST_STRING_TYPENAME
+ traits_type::size_type size_type;
+ typedef BOOST_STRING_TYPENAME
+ traits_type::difference_type difference_type;
+
+ typedef BOOST_STRING_TYPENAME
+ ::boost::mpl::if_< ::boost::is_const<T>,
+ const_iterator,
+ iterator
+ >::type result_iterator;
+
+ private:
+ // resolve array size
+ typedef BOOST_STRING_TYPENAME
+ ::boost::remove_cv<value_type>::type char_type;
+ typedef BOOST_STRING_TYPENAME
+ array_length_selector<char_type>::
+ BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
+
+ public:
+ BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
+
+ // static operations
+ template< typename A >
+ static size_type size( const A& a )
+ {
+ return array_length_type::length(a);
+ }
+
+ template< typename A >
+ static bool empty( const A& a )
+ {
+ return array_length_type::empty(a);
+ }
+
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< typename A >
+ static iterator begin( A& a )
+ {
+ return a;
+ }
+
+ template< typename A >
+ static const_iterator begin( const A& a )
+ {
+ return a;
+ }
+
+ template< typename A >
+ static iterator end( A& a )
+ {
+ return a+array_length_type::length(a);
+ }
+
+ template< typename A >
+ static const_iterator end( const A& a )
+ {
+ return a+array_length_type::length(a);
+ }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< typename A >
+ static result_iterator begin( A& a )
+ {
+ return a;
+ }
+
+ template< typename A >
+ static result_iterator end( A& a )
+ {
+ return a+array_length_type::length(a);
+ }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ };
+
+ template<typename T>
+ struct array_container_traits_selector
+ {
+ typedef array_container_traits<T> type;
+ };
+
+// Pointer container traits ---------------------------------------------------------------
+
+ template<typename T>
+ struct pointer_container_traits
+ {
+ typedef BOOST_STRING_TYPENAME
+ ::boost::remove_pointer<T>::type value_type;
+
+ typedef BOOST_STRING_TYPENAME
+ ::boost::remove_cv<value_type>::type char_type;
+ typedef ::std::char_traits<char_type> char_traits;
+
+ typedef value_type* iterator;
+ typedef const value_type* const_iterator;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type;
+
+ typedef BOOST_STRING_TYPENAME
+ ::boost::mpl::if_< ::boost::is_const<T>,
+ const_iterator,
+ iterator
+ >::type result_iterator;
+
+ // static operations
+ template< typename P >
+ static size_type size( const P& p )
+ {
+ if ( p==0 )
+ return 0;
+ else
+ return char_traits::length(p);
+ }
+
+ template< typename P >
+ static bool empty( const P& p )
+ {
+ return p==0 || p[0]==0;
+ }
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< typename P >
+ static iterator begin( P& p )
+ {
+ return p;
+ }
+
+ template< typename P >
+ static const_iterator begin( const P& p )
+ {
+ return p;
+ }
+
+ template< typename P >
+ static iterator end( P& p )
+ {
+ if ( p==0 )
+ return p;
+ else
+ return p+char_traits::length(p);
+ }
+
+ template< typename P >
+ static const_iterator end( const P& p )
+ {
+ if ( p==0 )
+ return p;
+ else
+ return p+char_traits::length(p);
+ }
+
+#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< typename P >
+ static result_iterator begin( P& p )
+ {
+ return p;
+ }
+
+ template< typename P >
+ static result_iterator end( P& p )
+ {
+ if ( p==0 )
+ return p;
+ else
+ return p+char_traits::length(p);
+ }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+ };
+
+ template<typename T>
+ struct pointer_container_traits_selector
+ {
+ typedef pointer_container_traits<T> type;
+ };
+
+ } // namespace detail
+ } // namespace algorithm
+} // namespace boost
+
+
+#endif // BOOST_STRING_DETAIL_COLLECTION_HPP
diff --git a/src/boost/range/detail/common.hpp b/src/boost/range/detail/common.hpp
new file mode 100644
index 0000000..f7539f5
--- /dev/null
+++ b/src/boost/range/detail/common.hpp
@@ -0,0 +1,117 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_COMMON_HPP
+#define BOOST_RANGE_DETAIL_COMMON_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/detail/sfinae.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/detail/ice_or.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/int.hpp>
+#include <cstddef>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost
+{
+ namespace range_detail
+ {
+ // 1 = std containers
+ // 2 = std::pair
+ // 3 = const std::pair
+ // 4 = array
+ // 5 = const array
+ // 6 = char array
+ // 7 = wchar_t array
+ // 8 = char*
+ // 9 = const char*
+ // 10 = whar_t*
+ // 11 = const wchar_t*
+ // 12 = string
+
+ typedef mpl::int_<1>::type std_container_;
+ typedef mpl::int_<2>::type std_pair_;
+ typedef mpl::int_<3>::type const_std_pair_;
+ typedef mpl::int_<4>::type array_;
+ typedef mpl::int_<5>::type const_array_;
+ typedef mpl::int_<6>::type char_array_;
+ typedef mpl::int_<7>::type wchar_t_array_;
+ typedef mpl::int_<8>::type char_ptr_;
+ typedef mpl::int_<9>::type const_char_ptr_;
+ typedef mpl::int_<10>::type wchar_t_ptr_;
+ typedef mpl::int_<11>::type const_wchar_t_ptr_;
+ typedef mpl::int_<12>::type string_;
+
+ template< typename C >
+ struct range_helper
+ {
+ static C* c;
+ static C ptr;
+
+ BOOST_STATIC_CONSTANT( bool, is_pair_ = sizeof( boost::range_detail::is_pair_impl( c ) ) == sizeof( yes_type ) );
+ BOOST_STATIC_CONSTANT( bool, is_char_ptr_ = sizeof( boost::range_detail::is_char_ptr_impl( ptr ) ) == sizeof( yes_type ) );
+ BOOST_STATIC_CONSTANT( bool, is_const_char_ptr_ = sizeof( boost::range_detail::is_const_char_ptr_impl( ptr ) ) == sizeof( yes_type ) );
+ BOOST_STATIC_CONSTANT( bool, is_wchar_t_ptr_ = sizeof( boost::range_detail::is_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
+ BOOST_STATIC_CONSTANT( bool, is_const_wchar_t_ptr_ = sizeof( boost::range_detail::is_const_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
+ BOOST_STATIC_CONSTANT( bool, is_char_array_ = sizeof( boost::range_detail::is_char_array_impl( ptr ) ) == sizeof( yes_type ) );
+ BOOST_STATIC_CONSTANT( bool, is_wchar_t_array_ = sizeof( boost::range_detail::is_wchar_t_array_impl( ptr ) ) == sizeof( yes_type ) );
+ BOOST_STATIC_CONSTANT( bool, is_string_ = (boost::type_traits::ice_or<is_const_char_ptr_, is_const_wchar_t_ptr_>::value ));
+ BOOST_STATIC_CONSTANT( bool, is_array_ = boost::is_array<C>::value );
+
+ };
+
+ template< typename C >
+ class range
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_pair_,
+ boost::range_detail::std_pair_,
+ void >::type pair_t;
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_array_,
+ boost::range_detail::array_,
+ pair_t >::type array_t;
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_string_,
+ boost::range_detail::string_,
+ array_t >::type string_t;
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_const_char_ptr_,
+ boost::range_detail::const_char_ptr_,
+ string_t >::type const_char_ptr_t;
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_char_ptr_,
+ boost::range_detail::char_ptr_,
+ const_char_ptr_t >::type char_ptr_t;
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_const_wchar_t_ptr_,
+ boost::range_detail::const_wchar_t_ptr_,
+ char_ptr_t >::type const_wchar_ptr_t;
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_wchar_t_ptr_,
+ boost::range_detail::wchar_t_ptr_,
+ const_wchar_ptr_t >::type wchar_ptr_t;
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_wchar_t_array_,
+ boost::range_detail::wchar_t_array_,
+ wchar_ptr_t >::type wchar_array_t;
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::range_detail::range_helper<C>::is_char_array_,
+ boost::range_detail::char_array_,
+ wchar_array_t >::type char_array_t;
+ public:
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< ::boost::is_void<char_array_t>::value,
+ boost::range_detail::std_container_,
+ char_array_t >::type type;
+ }; // class 'range'
+ }
+}
+
+#endif
+
diff --git a/src/boost/range/detail/const_iterator.hpp b/src/boost/range/detail/const_iterator.hpp
new file mode 100644
index 0000000..e5cb34a
--- /dev/null
+++ b/src/boost/range/detail/const_iterator.hpp
@@ -0,0 +1,71 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_CONST_ITERATOR_HPP
+#define BOOST_RANGE_DETAIL_CONST_ITERATOR_HPP
+
+#include <boost/range/detail/common.hpp>
+#include <boost/range/detail/remove_extent.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_const_iterator_;
+
+ template<>
+ struct range_const_iterator_<std_container_>
+ {
+ template< typename C >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME C::const_iterator type;
+ };
+ };
+
+ template<>
+ struct range_const_iterator_<std_pair_>
+ {
+ template< typename P >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME P::first_type type;
+ };
+ };
+
+
+ template<>
+ struct range_const_iterator_<array_>
+ {
+ template< typename T >
+ struct pts
+ {
+ typedef const BOOST_RANGE_DEDUCED_TYPENAME
+ remove_extent<T>::type* type;
+ };
+ };
+ }
+
+ template< typename C >
+ class range_const_iterator
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
+ public:
+ typedef BOOST_DEDUCED_TYPENAME range_detail::range_const_iterator_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
+ };
+
+}
+
+#endif
diff --git a/src/boost/range/detail/demote_iterator_traversal_tag.hpp b/src/boost/range/detail/demote_iterator_traversal_tag.hpp
new file mode 100644
index 0000000..2127de9
--- /dev/null
+++ b/src/boost/range/detail/demote_iterator_traversal_tag.hpp
@@ -0,0 +1,91 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Acknowledgements:
+// aschoedl supplied a fix to supply the level of interoperability I had
+// originally intended, but failed to implement.
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_DEMOTE_ITERATOR_TRAVERSAL_TAG_HPP_INCLUDED
+
+#include <boost/iterator/iterator_categories.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+
+template<class IteratorTraversalTag1, class IteratorTraversalTag2>
+struct inner_demote_iterator_traversal_tag
+{
+};
+
+#define BOOST_DEMOTE_TRAVERSAL_TAG( Tag1, Tag2, ResultTag ) \
+template<> struct inner_demote_iterator_traversal_tag< Tag1 , Tag2 > \
+{ \
+ typedef ResultTag type; \
+};
+
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, no_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, incrementable_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, single_pass_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, forward_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, bidirectional_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( no_traversal_tag, random_access_traversal_tag, no_traversal_tag )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, no_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, single_pass_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, forward_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, bidirectional_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( incrementable_traversal_tag, random_access_traversal_tag, incrementable_traversal_tag )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, no_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, single_pass_traversal_tag, single_pass_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, forward_traversal_tag, single_pass_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, bidirectional_traversal_tag, single_pass_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( single_pass_traversal_tag, random_access_traversal_tag, single_pass_traversal_tag )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, no_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, single_pass_traversal_tag, single_pass_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, forward_traversal_tag, forward_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, bidirectional_traversal_tag, forward_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( forward_traversal_tag, random_access_traversal_tag, forward_traversal_tag )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, no_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, single_pass_traversal_tag, single_pass_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, forward_traversal_tag, forward_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( bidirectional_traversal_tag, random_access_traversal_tag, bidirectional_traversal_tag )
+
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, no_traversal_tag, no_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, incrementable_traversal_tag, incrementable_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, single_pass_traversal_tag, single_pass_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, forward_traversal_tag, forward_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, bidirectional_traversal_tag, bidirectional_traversal_tag )
+BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, random_access_traversal_tag, random_access_traversal_tag )
+
+#undef BOOST_DEMOTE_TRAVERSAL_TAG
+
+template<class IteratorTraversalTag1, class IteratorTraversalTag2>
+struct demote_iterator_traversal_tag
+ : inner_demote_iterator_traversal_tag<
+ typename boost::detail::pure_traversal_tag< IteratorTraversalTag1 >::type,
+ typename boost::detail::pure_traversal_tag< IteratorTraversalTag2 >::type
+ >
+{
+};
+
+ } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/detail/detail_str.hpp b/src/boost/range/detail/detail_str.hpp
new file mode 100644
index 0000000..5ef7a34
--- /dev/null
+++ b/src/boost/range/detail/detail_str.hpp
@@ -0,0 +1,376 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_DETAIL_STR_HPP
+#define BOOST_RANGE_DETAIL_DETAIL_STR_HPP
+
+#include <boost/config.hpp> // BOOST_MSVC
+#include <boost/range/iterator.hpp>
+
+namespace boost
+{
+
+ namespace range_detail
+ {
+ //
+ // iterator
+ //
+
+ template<>
+ struct range_iterator_<char_array_>
+ {
+ template< typename T >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME
+ remove_extent<T>::type* type;
+ };
+ };
+
+ template<>
+ struct range_iterator_<char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef char* type;
+ };
+ };
+
+ template<>
+ struct range_iterator_<const_char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef const char* type;
+ };
+ };
+
+ template<>
+ struct range_iterator_<wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef wchar_t* type;
+ };
+ };
+
+ template<>
+ struct range_iterator_<const_wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef const wchar_t* type;
+ };
+ };
+
+
+ //
+ // const iterator
+ //
+
+ template<>
+ struct range_const_iterator_<char_array_>
+ {
+ template< typename T >
+ struct pts
+ {
+ typedef const BOOST_RANGE_DEDUCED_TYPENAME
+ remove_extent<T>::type* type;
+ };
+ };
+
+ template<>
+ struct range_const_iterator_<char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef const char* type;
+ };
+ };
+
+ template<>
+ struct range_const_iterator_<const_char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef const char* type;
+ };
+ };
+
+ template<>
+ struct range_const_iterator_<wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef const wchar_t* type;
+ };
+ };
+
+ template<>
+ struct range_const_iterator_<const_wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef const wchar_t* type;
+ };
+ };
+ }
+}
+
+#include <boost/range/detail/begin.hpp>
+#include <boost/range/detail/end.hpp>
+#include <boost/range/detail/size_type.hpp>
+#include <boost/range/detail/value_type.hpp>
+#include <boost/range/detail/common.hpp>
+
+namespace boost
+{
+
+ namespace range_detail
+ {
+ //
+ // str_begin()
+ //
+ template<>
+ struct range_begin<char_ptr_>
+ {
+ static char* fun( char* s )
+ {
+ return s;
+ }
+ };
+
+ template<>
+ struct range_begin<const_char_ptr_>
+ {
+ static const char* fun( const char* s )
+ {
+ return s;
+ }
+ };
+
+ template<>
+ struct range_begin<wchar_t_ptr_>
+ {
+
+ static wchar_t* fun( wchar_t* s )
+ {
+ return s;
+ }
+ };
+
+ template<>
+ struct range_begin<const_wchar_t_ptr_>
+ {
+ static const wchar_t* fun( const wchar_t* s )
+ {
+ return s;
+ }
+ };
+
+ template< typename C >
+ inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
+ str_begin( C& c )
+ {
+ return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME
+ range_detail::range<C>::type >::fun( c );
+ }
+
+ //
+ // str_end()
+ //
+
+ template<>
+ struct range_end<char_array_>
+ {
+ template< typename T, std::size_t sz >
+ static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return boost::range_detail::array_end( boost_range_array );
+ }
+ };
+
+ template<>
+ struct range_end<wchar_t_array_>
+ {
+ template< typename T, std::size_t sz >
+ static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return boost::range_detail::array_end( boost_range_array );
+ }
+ };
+
+ template<>
+ struct range_end<char_ptr_>
+ {
+ static char* fun( char* s )
+ {
+ return boost::range_detail::str_end( s );
+ }
+ };
+
+ template<>
+ struct range_end<const_char_ptr_>
+ {
+ static const char* fun( const char* s )
+ {
+ return boost::range_detail::str_end( s );
+ }
+ };
+
+ template<>
+ struct range_end<wchar_t_ptr_>
+ {
+ static wchar_t* fun( wchar_t* s )
+ {
+ return boost::range_detail::str_end( s );
+ }
+ };
+
+
+ template<>
+ struct range_end<const_wchar_t_ptr_>
+ {
+ static const wchar_t* fun( const wchar_t* s )
+ {
+ return boost::range_detail::str_end( s );
+ }
+ };
+
+ template< typename C >
+ inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
+ str_end( C& c )
+ {
+ return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME
+ range_detail::range<C>::type >::fun( c );
+ }
+
+ //
+ // size_type
+ //
+
+ template<>
+ struct range_size_type_<char_array_>
+ {
+ template< typename A >
+ struct pts
+ {
+ typedef std::size_t type;
+ };
+ };
+
+ template<>
+ struct range_size_type_<char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef std::size_t type;
+ };
+ };
+
+ template<>
+ struct range_size_type_<const_char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef std::size_t type;
+ };
+ };
+
+ template<>
+ struct range_size_type_<wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef std::size_t type;
+ };
+ };
+
+ template<>
+ struct range_size_type_<const_wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef std::size_t type;
+ };
+ };
+
+ //
+ // value_type
+ //
+
+ template<>
+ struct range_value_type_<char_array_>
+ {
+ template< typename T >
+ struct pts
+ {
+ typedef char type;
+ };
+ };
+
+ template<>
+ struct range_value_type_<char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef char type;
+ };
+ };
+
+ template<>
+ struct range_value_type_<const_char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef const char type;
+ };
+ };
+
+ template<>
+ struct range_value_type_<wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef wchar_t type;
+ };
+ };
+
+ template<>
+ struct range_value_type_<const_wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef const wchar_t type;
+ };
+ };
+
+ } // namespace 'range_detail'
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/src/boost/range/detail/difference_type.hpp b/src/boost/range/detail/difference_type.hpp
new file mode 100644
index 0000000..c641516
--- /dev/null
+++ b/src/boost/range/detail/difference_type.hpp
@@ -0,0 +1,121 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP
+#define BOOST_RANGE_DETAIL_DIFFERENCE_TYPE_HPP
+
+#include <boost/range/detail/common.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_difference_type_;
+
+ template<>
+ struct range_difference_type_<std_container_>
+ {
+ template< typename C >
+ struct pts
+ {
+ typedef BOOST_DEDUCED_TYPENAME C::difference_type type;
+ };
+ };
+
+ template<>
+ struct range_difference_type_<std_pair_>
+ {
+ template< typename P >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_difference< BOOST_DEDUCED_TYPENAME P::first_type>::type type;
+ };
+ };
+
+ template<>
+ struct range_difference_type_<array_>
+ {
+ template< typename A >
+ struct pts
+ {
+ typedef std::ptrdiff_t type;
+ };
+ };
+
+ template<>
+ struct range_difference_type_<char_array_>
+ {
+ template< typename A >
+ struct pts
+ {
+ typedef std::ptrdiff_t type;
+ };
+ };
+
+ template<>
+ struct range_difference_type_<char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef std::ptrdiff_t type;
+ };
+ };
+
+ template<>
+ struct range_difference_type_<const_char_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef std::ptrdiff_t type;
+ };
+ };
+
+ template<>
+ struct range_difference_type_<wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef std::ptrdiff_t type;
+ };
+ };
+
+ template<>
+ struct range_difference_type_<const_wchar_t_ptr_>
+ {
+ template< typename S >
+ struct pts
+ {
+ typedef std::ptrdiff_t type;
+ };
+ };
+
+ }
+
+ template< typename C >
+ class range_difference
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
+ public:
+ typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range_difference_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
+ };
+
+}
+
+#endif
+
diff --git a/src/boost/range/detail/empty.hpp b/src/boost/range/detail/empty.hpp
new file mode 100644
index 0000000..b098705
--- /dev/null
+++ b/src/boost/range/detail/empty.hpp
@@ -0,0 +1,120 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_EMPTY_HPP
+#define BOOST_RANGE_DETAIL_EMPTY_HPP
+
+#include <boost/range/detail/common.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_empty;
+
+ //////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_empty<std_container_>
+ {
+ template< typename C >
+ static bool fun( C& c )
+ {
+ return c.empty();
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_empty<std_pair_>
+ {
+ template< typename P >
+ static bool fun( const P& p )
+ {
+ return p.first == p.second;
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_empty<array_>
+ {
+ template< typename T, std::size_t sz >
+ static bool fun( T BOOST_ARRAY_REF[sz] )
+ {
+ if( boost_range_array == 0 )
+ return true;
+ return false;
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // string
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_empty<char_ptr_>
+ {
+ static bool fun( const char* s )
+ {
+ return s == 0 || s[0] == 0;
+ }
+ };
+
+ template<>
+ struct range_empty<const_char_ptr_>
+ {
+ static bool fun( const char* s )
+ {
+ return s == 0 || s[0] == 0;
+ }
+ };
+
+ template<>
+ struct range_empty<wchar_t_ptr_>
+ {
+ static bool fun( const wchar_t* s )
+ {
+ return s == 0 || s[0] == 0;
+ }
+ };
+
+ template<>
+ struct range_empty<const_wchar_t_ptr_>
+ {
+ static bool fun( const wchar_t* s )
+ {
+ return s == 0 || s[0] == 0;
+ }
+ };
+
+ } // namespace 'range_detail'
+
+
+ template< typename C >
+ inline bool
+ empty( const C& c )
+ {
+ return range_detail::range_empty< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
+ }
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/src/boost/range/detail/end.hpp b/src/boost/range/detail/end.hpp
new file mode 100644
index 0000000..8b5f35d
--- /dev/null
+++ b/src/boost/range/detail/end.hpp
@@ -0,0 +1,101 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_END_HPP
+#define BOOST_RANGE_DETAIL_END_HPP
+
+#include <boost/config.hpp> // BOOST_MSVC
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+# include <boost/range/detail/vc6/end.hpp>
+#else
+# include <boost/range/detail/implementation_help.hpp>
+# include <boost/range/iterator.hpp>
+# include <boost/range/detail/common.hpp>
+# if BOOST_WORKAROUND(BOOST_MSVC, < 1310)
+# include <boost/range/detail/remove_extent.hpp>
+# endif
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_end;
+
+ //////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_end<std_container_>
+ {
+ template< typename C >
+ static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
+ fun( C& c )
+ {
+ return c.end();
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_end<std_pair_>
+ {
+ template< typename P >
+ static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type
+ fun( const P& p )
+ {
+ return p.second;
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_end<array_>
+ {
+ #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)
+ template< typename T, std::size_t sz >
+ static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return boost::range_detail::array_end( boost_range_array );
+ }
+ #else
+ template<typename T>
+ static BOOST_RANGE_DEDUCED_TYPENAME remove_extent<T>::type* fun(T& t)
+ {
+ return t + remove_extent<T>::size;
+ }
+ #endif
+ };
+
+ } // namespace 'range_detail'
+
+ namespace range_adl_barrier
+ {
+ template< typename C >
+ inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
+ end( C& c )
+ {
+ return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
+ }
+ } // namespace range_adl_barrier
+
+} // namespace 'boost'
+
+# endif // VC6
+#endif
diff --git a/src/boost/range/detail/extract_optional_type.hpp b/src/boost/range/detail/extract_optional_type.hpp
new file mode 100644
index 0000000..8292e34
--- /dev/null
+++ b/src/boost/range/detail/extract_optional_type.hpp
@@ -0,0 +1,52 @@
+// Boost.Range library
+//
+// Copyright Arno Schoedl & Neil Groves 2009.
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_EXTRACT_OPTIONAL_TYPE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef ) \
+ template< typename C > \
+ struct extract_ ## a_typedef \
+ { \
+ typedef BOOST_DEDUCED_TYPENAME C::a_typedef type; \
+ };
+
+#else
+
+namespace boost {
+ namespace range_detail {
+ template< typename T > struct exists { typedef void type; };
+ }
+}
+
+// Defines extract_some_typedef<T> which exposes T::some_typedef as
+// extract_some_typedef<T>::type if T::some_typedef exists. Otherwise
+// extract_some_typedef<T> is empty.
+#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef ) \
+ template< typename C, typename Enable=void > \
+ struct extract_ ## a_typedef \
+ {}; \
+ template< typename C > \
+ struct extract_ ## a_typedef< C \
+ , BOOST_DEDUCED_TYPENAME boost::range_detail::exists< BOOST_DEDUCED_TYPENAME C::a_typedef >::type \
+ > { \
+ typedef BOOST_DEDUCED_TYPENAME C::a_typedef type; \
+ };
+
+#endif
+
+#endif // include guard
diff --git a/src/boost/range/detail/implementation_help.hpp b/src/boost/range/detail/implementation_help.hpp
new file mode 100644
index 0000000..1f7d163
--- /dev/null
+++ b/src/boost/range/detail/implementation_help.hpp
@@ -0,0 +1,103 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
+#define BOOST_RANGE_DETAIL_IMPLEMENTATION_HELP_HPP
+
+#include <boost/range/config.hpp>
+#include <boost/range/detail/common.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <cstddef>
+#include <string.h>
+
+#ifndef BOOST_NO_CWCHAR
+#include <wchar.h>
+#endif
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template <typename T>
+ inline void boost_range_silence_warning( const T& ) { }
+
+ /////////////////////////////////////////////////////////////////////
+ // end() help
+ /////////////////////////////////////////////////////////////////////
+
+ inline const char* str_end( const char* s, const char* )
+ {
+ return s + strlen( s );
+ }
+
+#ifndef BOOST_NO_CWCHAR
+ inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
+ {
+ return s + wcslen( s );
+ }
+#else
+ inline const wchar_t* str_end( const wchar_t* s, const wchar_t* )
+ {
+ if( s == 0 || s[0] == 0 )
+ return s;
+ while( *++s != 0 )
+ ;
+ return s;
+ }
+#endif
+
+ template< class Char >
+ inline Char* str_end( Char* s )
+ {
+ return const_cast<Char*>( str_end( s, s ) );
+ }
+
+ template< class T, std::size_t sz >
+ inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return boost_range_array + sz;
+ }
+
+ template< class T, std::size_t sz >
+ inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return boost_range_array + sz;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ // size() help
+ /////////////////////////////////////////////////////////////////////
+
+ template< class Char >
+ inline std::size_t str_size( const Char* const& s )
+ {
+ return str_end( s ) - s;
+ }
+
+ template< class T, std::size_t sz >
+ inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ boost_range_silence_warning( boost_range_array );
+ return sz;
+ }
+
+ template< class T, std::size_t sz >
+ inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ boost_range_silence_warning( boost_range_array );
+ return sz;
+ }
+
+ } // namespace 'range_detail'
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/src/boost/range/detail/iterator.hpp b/src/boost/range/detail/iterator.hpp
new file mode 100644
index 0000000..58346d4
--- /dev/null
+++ b/src/boost/range/detail/iterator.hpp
@@ -0,0 +1,78 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_ITERATOR_HPP
+#define BOOST_RANGE_DETAIL_ITERATOR_HPP
+
+#include <boost/range/detail/common.hpp>
+#include <boost/range/detail/remove_extent.hpp>
+
+#include <boost/static_assert.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_iterator_ {
+ template< typename C >
+ struct pts
+ {
+ typedef int type;
+ };
+ };
+
+ template<>
+ struct range_iterator_<std_container_>
+ {
+ template< typename C >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME C::iterator type;
+ };
+ };
+
+ template<>
+ struct range_iterator_<std_pair_>
+ {
+ template< typename P >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME P::first_type type;
+ };
+ };
+
+ template<>
+ struct range_iterator_<array_>
+ {
+ template< typename T >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME
+ remove_extent<T>::type* type;
+ };
+ };
+
+ }
+
+ template< typename C >
+ class range_mutable_iterator
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
+ public:
+ typedef typename range_detail::range_iterator_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
+ };
+}
+
+#endif
diff --git a/src/boost/range/detail/join_iterator.hpp b/src/boost/range/detail/join_iterator.hpp
new file mode 100644
index 0000000..bbdeec7
--- /dev/null
+++ b/src/boost/range/detail/join_iterator.hpp
@@ -0,0 +1,344 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Acknowledgements:
+// aschoedl contributed an improvement to the determination
+// of the Reference type parameter.
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED
+
+#include <iterator>
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/empty.hpp>
+#include <boost/range/detail/demote_iterator_traversal_tag.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/next_prior.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+
+template<typename Iterator1, typename Iterator2>
+struct join_iterator_link
+{
+public:
+ join_iterator_link(Iterator1 last1, Iterator2 first2)
+ : last1(last1)
+ , first2(first2)
+ {
+ }
+
+ Iterator1 last1;
+ Iterator2 first2;
+
+private:
+ join_iterator_link() /* = delete */ ;
+};
+
+class join_iterator_begin_tag {};
+class join_iterator_end_tag {};
+
+template<typename Iterator1
+ , typename Iterator2
+ , typename Reference
+>
+class join_iterator_union
+{
+public:
+ typedef Iterator1 iterator1_t;
+ typedef Iterator2 iterator2_t;
+
+ join_iterator_union() {}
+ join_iterator_union(unsigned int /*selected*/, const iterator1_t& it1, const iterator2_t& it2) : m_it1(it1), m_it2(it2) {}
+
+ iterator1_t& it1() { return m_it1; }
+ const iterator1_t& it1() const { return m_it1; }
+
+ iterator2_t& it2() { return m_it2; }
+ const iterator2_t& it2() const { return m_it2; }
+
+ Reference dereference(unsigned int selected) const
+ {
+ return selected ? *m_it2 : *m_it1;
+ }
+
+ bool equal(const join_iterator_union& other, unsigned int selected) const
+ {
+ return selected
+ ? m_it2 == other.m_it2
+ : m_it1 == other.m_it1;
+ }
+
+private:
+ iterator1_t m_it1;
+ iterator2_t m_it2;
+};
+
+template<class Iterator, class Reference>
+class join_iterator_union<Iterator, Iterator, Reference>
+{
+public:
+ typedef Iterator iterator1_t;
+ typedef Iterator iterator2_t;
+
+ join_iterator_union() {}
+
+ join_iterator_union(unsigned int selected, const iterator1_t& it1, const iterator2_t& it2)
+ : m_it(selected ? it2 : it1)
+ {
+ }
+
+ iterator1_t& it1() { return m_it; }
+ const iterator1_t& it1() const { return m_it; }
+
+ iterator2_t& it2() { return m_it; }
+ const iterator2_t& it2() const { return m_it; }
+
+ Reference dereference(unsigned int) const
+ {
+ return *m_it;
+ }
+
+ bool equal(const join_iterator_union& other, unsigned int selected) const
+ {
+ return m_it == other.m_it;
+ }
+
+private:
+ iterator1_t m_it;
+};
+
+template<typename Iterator1
+ , typename Iterator2
+ , typename ValueType = typename iterator_value<Iterator1>::type
+ // find least demanding, commonly supported reference type, in the order &, const&, and by-value:
+ , typename Reference = typename mpl::if_c<
+ !is_reference<typename iterator_reference<Iterator1>::type>::value
+ || !is_reference<typename iterator_reference<Iterator2>::type>::value,
+ typename remove_const<
+ typename remove_reference<
+ typename iterator_reference<Iterator1>::type
+ >::type
+ >::type,
+ typename mpl::if_c<
+ is_const<
+ typename remove_reference<
+ typename iterator_reference<Iterator1>::type
+ >::type
+ >::value
+ || is_const<
+ typename remove_reference<
+ typename iterator_reference<Iterator2>::type
+ >::type
+ >::value,
+ typename add_const<
+ typename iterator_reference<Iterator2>::type
+ >::type,
+ typename iterator_reference<Iterator1>::type
+ >::type
+ >::type
+ , typename Traversal = typename demote_iterator_traversal_tag<
+ typename iterator_traversal<Iterator1>::type
+ , typename iterator_traversal<Iterator2>::type>::type
+>
+class join_iterator
+ : public iterator_facade<join_iterator<Iterator1,Iterator2,ValueType,Reference,Traversal>, ValueType, Traversal, Reference>
+{
+ typedef join_iterator_link<Iterator1, Iterator2> link_t;
+ typedef join_iterator_union<Iterator1, Iterator2, Reference> iterator_union;
+public:
+ typedef Iterator1 iterator1_t;
+ typedef Iterator2 iterator2_t;
+
+ join_iterator()
+ : m_section(0u)
+ , m_it(0u, iterator1_t(), iterator2_t())
+ , m_link(link_t(iterator1_t(), iterator2_t()))
+ {}
+
+ join_iterator(unsigned int section, Iterator1 current1, Iterator1 last1, Iterator2 first2, Iterator2 current2)
+ : m_section(section)
+ , m_it(section, current1, current2)
+ , m_link(link_t(last1, first2))
+ {
+ }
+
+ template<typename Range1, typename Range2>
+ join_iterator(Range1& r1, Range2& r2, join_iterator_begin_tag)
+ : m_section(boost::empty(r1) ? 1u : 0u)
+ , m_it(boost::empty(r1) ? 1u : 0u, boost::begin(r1), boost::begin(r2))
+ , m_link(link_t(boost::end(r1), boost::begin(r2)))
+ {
+ }
+
+ template<typename Range1, typename Range2>
+ join_iterator(const Range1& r1, const Range2& r2, join_iterator_begin_tag)
+ : m_section(boost::empty(r1) ? 1u : 0u)
+ , m_it(boost::empty(r1) ? 1u : 0u, boost::const_begin(r1), boost::const_begin(r2))
+ , m_link(link_t(boost::const_end(r1), boost::const_begin(r2)))
+ {
+ }
+
+ template<typename Range1, typename Range2>
+ join_iterator(Range1& r1, Range2& r2, join_iterator_end_tag)
+ : m_section(1u)
+ , m_it(1u, boost::end(r1), boost::end(r2))
+ , m_link(link_t(boost::end(r1), boost::begin(r2)))
+ {
+ }
+
+ template<typename Range1, typename Range2>
+ join_iterator(const Range1& r1, const Range2& r2, join_iterator_end_tag)
+ : m_section(1u)
+ , m_it(1u, boost::const_end(r1), boost::const_end(r2))
+ , m_link(link_t(boost::const_end(r1), boost::const_begin(r2)))
+ {
+ }
+
+private:
+ void increment()
+ {
+ if (m_section)
+ ++m_it.it2();
+ else
+ {
+ ++m_it.it1();
+ if (m_it.it1() == m_link.last1)
+ {
+ m_it.it2() = m_link.first2;
+ m_section = 1u;
+ }
+ }
+ }
+
+ void decrement()
+ {
+ if (m_section)
+ {
+ if (m_it.it2() == m_link.first2)
+ {
+ m_it.it1() = boost::prior(m_link.last1);
+ m_section = 0u;
+ }
+ else
+ --m_it.it2();
+ }
+ else
+ --m_it.it1();
+ }
+
+ typename join_iterator::reference dereference() const
+ {
+ return m_it.dereference(m_section);
+ }
+
+ bool equal(const join_iterator& other) const
+ {
+ return m_section == other.m_section
+ && m_it.equal(other.m_it, m_section);
+ }
+
+ void advance(typename join_iterator::difference_type offset)
+ {
+ if (m_section)
+ advance_from_range2(offset);
+ else
+ advance_from_range1(offset);
+ }
+
+ typename join_iterator::difference_type distance_to(const join_iterator& other) const
+ {
+ typename join_iterator::difference_type result;
+ if (m_section)
+ {
+ if (other.m_section)
+ result = other.m_it.it2() - m_it.it2();
+ else
+ {
+ result = (m_link.first2 - m_it.it2())
+ + (other.m_it.it1() - m_link.last1);
+
+ BOOST_ASSERT( result <= 0 );
+ }
+ }
+ else
+ {
+ if (other.m_section)
+ {
+ result = (m_link.last1 - m_it.it1())
+ + (other.m_it.it2() - m_link.first2);
+ }
+ else
+ result = other.m_it.it1() - m_it.it1();
+ }
+ return result;
+ }
+
+ void advance_from_range2(typename join_iterator::difference_type offset)
+ {
+ typedef typename join_iterator::difference_type difference_t;
+ BOOST_ASSERT( m_section == 1u );
+ if (offset < 0)
+ {
+ difference_t r2_dist = m_link.first2 - m_it.it2();
+ BOOST_ASSERT( r2_dist <= 0 );
+ if (offset >= r2_dist)
+ std::advance(m_it.it2(), offset);
+ else
+ {
+ difference_t r1_dist = offset - r2_dist;
+ BOOST_ASSERT( r1_dist <= 0 );
+ m_it.it1() = m_link.last1 + r1_dist;
+ m_section = 0u;
+ }
+ }
+ else
+ std::advance(m_it.it2(), offset);
+ }
+
+ void advance_from_range1(typename join_iterator::difference_type offset)
+ {
+ typedef typename join_iterator::difference_type difference_t;
+ BOOST_ASSERT( m_section == 0u );
+ if (offset > 0)
+ {
+ difference_t r1_dist = m_link.last1 - m_it.it1();
+ BOOST_ASSERT( r1_dist >= 0 );
+ if (offset < r1_dist)
+ std::advance(m_it.it1(), offset);
+ else
+ {
+ difference_t r2_dist = offset - r1_dist;
+ BOOST_ASSERT( r2_dist >= 0 );
+ m_it.it2() = m_link.first2 + r2_dist;
+ m_section = 1u;
+ }
+ }
+ else
+ std::advance(m_it.it1(), offset);
+ }
+
+ unsigned int m_section;
+ iterator_union m_it;
+ link_t m_link;
+
+ friend class ::boost::iterator_core_access;
+};
+
+ } // namespace range_detail
+
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/detail/microsoft.hpp b/src/boost/range/detail/microsoft.hpp
new file mode 100644
index 0000000..7b672c9
--- /dev/null
+++ b/src/boost/range/detail/microsoft.hpp
@@ -0,0 +1,931 @@
+#ifndef BOOST_RANGE_DETAIL_MICROSOFT_HPP
+#define BOOST_RANGE_DETAIL_MICROSOFT_HPP
+
+// Boost.Range MFC/ATL Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+
+// config
+//
+
+
+#include <boost/range/iterator.hpp>
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1 1
+
+
+#if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+ #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
+ #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin range_begin
+ #define BOOST_RANGE_DETAIL_MICROSOFT_range_end range_end
+#else
+ #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
+ #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin range_begin
+ #define BOOST_RANGE_DETAIL_MICROSOFT_range_end range_end
+#endif
+
+
+
+
+// yet another customization way
+//
+
+
+#include <boost/iterator/iterator_traits.hpp> // iterator_difference
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/comma_if.hpp>
+#include <boost/preprocessor/detail/is_unary.hpp>
+#include <boost/preprocessor/list/for_each.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/tuple/eat.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/utility/enable_if.hpp> // disable_if
+
+#if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+ #include <boost/range/mutable_iterator.hpp>
+#else
+ #include <iterator> // distance
+ #include <boost/range/begin.hpp>
+ #include <boost/range/end.hpp>
+ #include <boost/range/iterator.hpp>
+#endif
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+ // customization point
+ //
+
+ template< class Tag >
+ struct customization;
+
+
+ template< class T >
+ struct customization_tag;
+
+
+ struct using_type_as_tag
+ { };
+
+
+ // Topic:
+ // In fact, it is unnecessary for VC++.
+ // VC++'s behavior seems conforming, while GCC fails without this.
+ template< class Iterator, class T >
+ struct mutable_ :
+ disable_if< is_const<T>, Iterator >
+ { };
+
+
+ // helpers
+ //
+
+ template< class Tag, class T >
+ struct customization_tag_of
+ {
+ typedef typename mpl::if_< is_same<using_type_as_tag, Tag>,
+ T,
+ Tag
+ >::type type;
+ };
+
+
+ template< class T >
+ struct customization_of
+ {
+ typedef typename remove_cv<T>::type bare_t;
+ typedef typename customization_tag<bare_t>::type tag_t;
+ typedef customization<tag_t> type;
+ };
+
+
+ template< class T >
+ struct mutable_iterator_of
+ {
+ typedef typename remove_cv<T>::type bare_t;
+ typedef typename customization_of<bare_t>::type cust_t;
+ typedef typename cust_t::template meta<bare_t>::mutable_iterator type;
+ };
+
+
+ template< class T >
+ struct const_iterator_of
+ {
+ typedef typename remove_cv<T>::type bare_t;
+ typedef typename customization_of<bare_t>::type cust_t;
+ typedef typename cust_t::template meta<bare_t>::const_iterator type;
+ };
+
+
+ template< class T >
+ struct size_type_of
+ {
+ typedef typename range_detail_microsoft::mutable_iterator_of<T>::type miter_t;
+ typedef typename iterator_difference<miter_t>::type type;
+ };
+
+
+ template< class T > inline
+ typename mutable_iterator_of<T>::type
+ begin_of(T& x)
+ {
+ typedef typename customization_of<T>::type cust_t;
+ return cust_t().template begin<typename mutable_iterator_of<T>::type>(x);
+ }
+
+
+ template< class T > inline
+ typename const_iterator_of<T>::type
+ begin_of(T const& x)
+ {
+ typedef typename customization_of<T>::type cust_t;
+ return cust_t().template begin<typename const_iterator_of<T>::type>(x);
+ }
+
+
+ template< class T > inline
+ typename mutable_iterator_of<T>::type
+ end_of(T& x)
+ {
+ typedef typename customization_of<T>::type cust_t;
+ return cust_t().template end<typename mutable_iterator_of<T>::type>(x);
+ }
+
+
+ template< class T > inline
+ typename const_iterator_of<T>::type
+ end_of(T const& x)
+ {
+ typedef typename customization_of<T>::type cust_t;
+ return cust_t().template end<typename const_iterator_of<T>::type>(x);
+ }
+
+
+#if defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+
+ template< class T > inline
+ typename size_type_of<T>::type
+ size_of(T const& x)
+ {
+ return std::distance(boost::begin(x), boost::end(x));
+ }
+
+#endif
+
+
+ template< class Range >
+ struct compatible_mutable_iterator :
+ BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>
+ { };
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
+ BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op, ~, NamespaceList) \
+/**/
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op(r, data, elem) \
+ namespace elem { \
+ /**/
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
+ BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op, ~, NamespaceList) \
+/**/
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op(r, data, elem) \
+ } \
+ /**/
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op(r, data, elem) \
+ :: elem \
+/**/
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(Tag, NamespaceList, Name) \
+ namespace boost { namespace range_detail_microsoft { \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ } } \
+ \
+ namespace boost { \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ } \
+ \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
+/**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name) \
+ BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) :: Name \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, Fullname) \
+ template< > \
+ struct customization_tag< Fullname > : \
+ customization_tag_of< Tag, Fullname > \
+ { }; \
+ /**/
+
+
+ // metafunctions
+ //
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(Fullname) \
+ template< > \
+ struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
+ range_detail_microsoft::mutable_iterator_of< Fullname > \
+ { }; \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(Fullname) \
+ template< > \
+ struct range_const_iterator< Fullname > : \
+ range_detail_microsoft::const_iterator_of< Fullname > \
+ { }; \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(Fullname) \
+ template< > \
+ struct range_size< Fullname > : \
+ range_detail_microsoft::size_type_of< Fullname > \
+ { }; \
+ /**/
+
+
+ // functions
+ //
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(Fullname) \
+ inline \
+ boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
+ BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
+ { \
+ return boost::range_detail_microsoft::begin_of(x); \
+ } \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(Fullname) \
+ inline \
+ boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
+ BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
+ { \
+ return boost::range_detail_microsoft::begin_of(x); \
+ } \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(Fullname) \
+ inline \
+ boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
+ BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
+ { \
+ return boost::range_detail_microsoft::end_of(x); \
+ } \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(Fullname) \
+ inline \
+ boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
+ BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
+ { \
+ return boost::range_detail_microsoft::end_of(x); \
+ } \
+ /**/
+
+
+ #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
+ /**/
+
+ #else
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
+ inline \
+ boost::range_detail_microsoft::size_type_of< Fullname >::type \
+ boost_range_size(Fullname const& x) \
+ { \
+ return boost::range_detail_microsoft::size_of(x); \
+ } \
+ /**/
+
+ #endif
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(Tag, NamespaceList, Name, ParamSeqOrCount) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl( \
+ Tag, NamespaceList, Name, \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
+ ) \
+/**/
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
+ BOOST_PP_IIF(BOOST_PP_IS_UNARY(ParamSeqOrCount), \
+ ParamSeqOrCount BOOST_PP_TUPLE_EAT(3), \
+ BOOST_PP_REPEAT \
+ )(ParamSeqOrCount, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op, ~) \
+ /**/
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op(z, n, _) \
+ (class) \
+ /**/
+
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl(Tag, NamespaceList, Name, ParamSeq) \
+ namespace boost { namespace range_detail_microsoft { \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag( \
+ Tag, \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ } } \
+ \
+ namespace boost { \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator( \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator( \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type( \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ } \
+ \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin( \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const( \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end( \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const( \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size( \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ ) \
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
+/**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq) \
+ BOOST_PP_SEQ_FOR_EACH_I(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op, ~, ParamSeq) \
+ /**/
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op(r, data, i, elem) \
+ BOOST_PP_COMMA_IF(i) elem BOOST_PP_CAT(T, i) \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
+ BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) \
+ :: Name < BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(ParamSeq), T) > \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag(Tag, Params, Fullname) \
+ template< Params > \
+ struct customization_tag< Fullname > : \
+ customization_tag_of< Tag, Fullname > \
+ { }; \
+ /**/
+
+
+ // metafunctions
+ //
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator(Params, Fullname) \
+ template< Params > \
+ struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
+ range_detail_microsoft::mutable_iterator_of< Fullname > \
+ { }; \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator(Params, Fullname) \
+ template< Params > \
+ struct range_const_iterator< Fullname > : \
+ range_detail_microsoft::const_iterator_of< Fullname > \
+ { }; \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type(Params, Fullname) \
+ template< Params > \
+ struct range_size< Fullname > : \
+ range_detail_microsoft::size_type_of< Fullname > \
+ { }; \
+ /**/
+
+
+ // functions
+ //
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin(Params, Fullname) \
+ template< Params > inline \
+ typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
+ BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
+ { \
+ return boost::range_detail_microsoft::begin_of(x); \
+ } \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const(Params, Fullname) \
+ template< Params > inline \
+ typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
+ BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
+ { \
+ return boost::range_detail_microsoft::begin_of(x); \
+ } \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end(Params, Fullname) \
+ template< Params > inline \
+ typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
+ BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
+ { \
+ return boost::range_detail_microsoft::end_of(x); \
+ } \
+ /**/
+
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const(Params, Fullname) \
+ template< Params > inline \
+ typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
+ BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
+ { \
+ return boost::range_detail_microsoft::end_of(x); \
+ } \
+ /**/
+
+
+ #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
+ /**/
+
+ #else
+
+ #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
+ template< Params > inline \
+ typename boost::range_detail_microsoft::size_type_of< Fullname >::type \
+ boost_range_size(Fullname const& x) \
+ { \
+ return boost::range_detail_microsoft::size_of(x); \
+ } \
+ /**/
+
+ #endif
+
+
+
+
+// list_iterator and helpers
+//
+
+
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+// POSITION's header is undocumented, so is NULL.
+//
+struct __POSITION; // incomplete, but used as just a pointer.
+typedef __POSITION *POSITION;
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+ template<
+ class ListT,
+ class Value,
+ class Reference,
+ class Traversal
+ >
+ struct list_iterator;
+
+
+ template<
+ class ListT,
+ class Value,
+ class Reference,
+ class Traversal
+ >
+ struct list_iterator_super
+ {
+ typedef typename mpl::if_< is_same<use_default, Reference>,
+ Value&,
+ Reference
+ >::type ref_t;
+
+ typedef typename mpl::if_< is_same<use_default, Traversal>,
+ bidirectional_traversal_tag,
+ Traversal
+ >::type trv_t;
+
+ typedef iterator_facade<
+ list_iterator<ListT, Value, Reference, Traversal>,
+ Value,
+ trv_t,
+ ref_t
+ > type;
+ };
+
+
+ template<
+ class ListT,
+ class Value,
+ class Reference = use_default,
+ class Traversal = use_default
+ >
+ struct list_iterator :
+ list_iterator_super<ListT, Value, Reference, Traversal>::type
+ {
+ private:
+ typedef list_iterator self_t;
+ typedef typename list_iterator_super<ListT, Value, Reference, Traversal>::type super_t;
+ typedef typename super_t::reference ref_t;
+
+ public:
+ explicit list_iterator()
+ { }
+
+ explicit list_iterator(ListT& lst, POSITION pos) :
+ m_plst(boost::addressof(lst)), m_pos(pos)
+ { }
+
+ template< class, class, class, class > friend struct list_iterator;
+ template< class ListT_, class Value_, class Reference_, class Traversal_>
+ list_iterator(list_iterator<ListT_, Value_, Reference_, Traversal_> const& other) :
+ m_plst(other.m_plst), m_pos(other.m_pos)
+ { }
+
+ private:
+ ListT *m_plst;
+ POSITION m_pos;
+
+ friend class iterator_core_access;
+ ref_t dereference() const
+ {
+ BOOST_ASSERT(m_pos != 0 && "out of range");
+ return m_plst->GetAt(m_pos);
+ }
+
+ // A B C D x
+ // Head Tail NULL(0)
+ //
+ void increment()
+ {
+ BOOST_ASSERT(m_pos != 0 && "out of range");
+ m_plst->GetNext(m_pos);
+ }
+
+ void decrement()
+ {
+ if (m_pos == 0) {
+ m_pos = m_plst->GetTailPosition();
+ return;
+ }
+
+ m_plst->GetPrev(m_pos);
+ }
+
+ bool equal(self_t const& other) const
+ {
+ BOOST_ASSERT(m_plst == other.m_plst && "iterators incompatible");
+ return m_pos == other.m_pos;
+ }
+ };
+
+
+ // customization helpers
+ //
+
+ struct array_functions
+ {
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ return x.GetData();
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return begin<Iterator>(x) + x.GetSize();
+ }
+ };
+
+
+ struct list_functions
+ {
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ return Iterator(x, x.GetHeadPosition());
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return Iterator(x, POSITION(0));
+ }
+ };
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+
+
+// test
+//
+
+
+#if defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
+
+
+#include <algorithm>
+#include <iterator>
+#include <vector>
+#include <boost/concept_check.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/empty.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/mutable_iterator.hpp>
+#include <boost/range/rbegin.hpp>
+#include <boost/range/rend.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+ template< class Range1, class Range2 >
+ bool test_equals(Range1 const& rng1, Range2 const& rng2)
+ {
+ return
+ boost::distance(rng1) == boost::distance(rng2) &&
+ std::equal(boost::begin(rng1), boost::end(rng1), boost::begin(rng2))
+ ;
+ }
+
+
+ template< class AssocContainer, class PairT >
+ bool test_find_key_and_mapped(AssocContainer const& ac, PairT const& pa)
+ {
+ typedef typename boost::range_const_iterator<AssocContainer>::type iter_t;
+ for (iter_t it = boost::const_begin(ac), last = boost::const_end(ac); it != last; ++it) {
+ if (it->first == pa.first && it->second == pa.second)
+ return true;
+ }
+
+ return false;
+ }
+
+
+ // test functions
+ //
+
+ template< class Range >
+ bool test_emptiness(Range& )
+ {
+ bool result = true;
+
+ Range emptyRng;
+ result = result && boost::empty(emptyRng);
+
+ return result;
+ }
+
+
+ template< class Range >
+ bool test_trivial(Range& rng)
+ {
+ bool result = true;
+
+ // convertibility check
+ typedef typename range_const_iterator<Range>::type citer_t;
+ citer_t cit = boost::begin(rng);
+ (void)cit; // unused
+
+ // mutability check
+ typedef typename range_value<Range>::type val_t;
+ val_t v = *boost::begin(rng);
+ *boost::begin(rng) = v;
+ result = result && *boost::begin(rng) == v;
+
+ return result;
+ }
+
+
+ template< class Range >
+ bool test_forward(Range& rng)
+ {
+ boost::function_requires< ForwardRangeConcept<Range> >();
+
+ bool result = (test_trivial)(rng);
+
+ typedef typename range_value<Range>::type val_t;
+
+ std::vector<val_t> saved;
+ std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
+ std::rotate(boost::begin(saved), boost::next(boost::begin(saved)), boost::end(saved));
+
+ std::rotate(boost::begin(rng), boost::next(boost::begin(rng)), boost::end(rng));
+
+ return result && (test_equals)(saved, rng);
+ };
+
+
+ template< class Range >
+ bool test_bidirectional(Range& rng)
+ {
+ boost::function_requires< BidirectionalRangeConcept<Range> >();
+
+ bool result = (test_forward)(rng);
+
+ typedef typename range_value<Range>::type val_t;
+
+ std::vector<val_t> saved;
+ std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
+
+ result = result && (test_equals)(
+ boost::make_iterator_range(boost::rbegin(saved), boost::rend(saved)),
+ boost::make_iterator_range(boost::rbegin(rng), boost::rend(rng))
+ );
+
+ return result;
+ }
+
+
+ template< class Range >
+ bool test_random_access(Range& rng)
+ {
+ boost::function_requires< RandomAccessRangeConcept<Range> >();
+
+ bool result = (test_bidirectional)(rng);
+
+ typedef typename range_value<Range>::type val_t;
+
+ std::vector<val_t> saved;
+ std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
+ std::sort(boost::begin(saved), boost::end(saved));
+
+ std::random_shuffle(boost::begin(rng), boost::end(rng));
+ std::sort(boost::begin(rng), boost::end(rng));
+ result = result && (test_equals)(rng, saved);
+
+ std::random_shuffle(boost::begin(rng), boost::end(rng));
+ std::stable_sort(boost::begin(rng), boost::end(rng));
+ result = result && (test_equals)(rng, saved);
+
+ std::random_shuffle(boost::begin(rng), boost::end(rng));
+ std::partial_sort(boost::begin(rng), boost::end(rng), boost::end(rng));
+ result = result && (test_equals)(rng, saved);
+
+ return result;
+ }
+
+
+ // initializer
+ //
+
+ template< class ArrayT, class SampleRange >
+ bool test_init_array(ArrayT& arr, SampleRange const& sample)
+ {
+ typedef typename range_const_iterator<SampleRange>::type iter_t;
+ typedef typename range_value<SampleRange>::type val_t;
+
+ for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+ val_t v = *it; // works around ATL3 CSimpleArray
+ arr.Add(v);
+ }
+
+ return (test_equals)(arr, sample);
+ }
+
+
+ template< class ListT, class SampleRange >
+ bool test_init_list(ListT& lst, SampleRange const& sample)
+ {
+ typedef typename range_const_iterator<SampleRange>::type iter_t;
+
+ for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+ lst.AddTail(*it);
+ }
+
+ return (test_equals)(lst, sample);
+ }
+
+
+ template< class StringT, class SampleRange >
+ bool test_init_string(StringT& str, SampleRange const& sample)
+ {
+ typedef typename range_const_iterator<SampleRange>::type iter_t;
+ typedef typename range_value<SampleRange>::type val_t;
+
+ for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+ str += *it;
+ }
+
+ return (test_equals)(str, sample);
+ }
+
+
+ template< class MapT, class SampleMap >
+ bool test_init_map(MapT& map, SampleMap const& sample)
+ {
+ typedef typename range_const_iterator<SampleMap>::type iter_t;
+
+ for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+ map.SetAt(it->first, it->second);
+ }
+
+ return boost::distance(map) == boost::distance(sample);
+ }
+
+
+ // metafunction test
+ //
+
+ template< class Range, class Iter >
+ struct test_mutable_iter :
+ boost::is_same< typename boost::BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>::type, Iter >
+ { };
+
+
+ template< class Range, class Iter >
+ struct test_const_iter :
+ boost::is_same< typename boost::range_const_iterator<Range>::type, Iter >
+ { };
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+#endif // defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
+
+
+
+#endif
diff --git a/src/boost/range/detail/misc_concept.hpp b/src/boost/range/detail/misc_concept.hpp
new file mode 100644
index 0000000..74cb919
--- /dev/null
+++ b/src/boost/range/detail/misc_concept.hpp
@@ -0,0 +1,33 @@
+// Boost.Range library concept checks
+//
+// Copyright Neil Groves 2009. Use, modification and distribution
+// are subject to the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef BOOST_RANGE_DETAIL_MISC_CONCEPT_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_MISC_CONCEPT_HPP_INCLUDED
+
+#include <boost/concept_check.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template<typename T1, typename T2>
+ class SameTypeConcept
+ {
+ public:
+ BOOST_CONCEPT_USAGE(SameTypeConcept)
+ {
+ same_type(a,b);
+ }
+ private:
+ template<typename T> void same_type(T,T) {}
+ T1 a;
+ T2 b;
+ };
+ }
+}
+
+#endif // include guard
diff --git a/src/boost/range/detail/range_return.hpp b/src/boost/range/detail/range_return.hpp
new file mode 100644
index 0000000..52a6073
--- /dev/null
+++ b/src/boost/range/detail/range_return.hpp
@@ -0,0 +1,180 @@
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED
+#define BOOST_RANGE_DETAIL_RANGE_RETURN_HPP_INCLUDED
+
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+ enum range_return_value
+ {
+ // (*) indicates the most common values
+ return_found, // only the found resulting iterator (*)
+ return_next, // next(found) iterator
+ return_prior, // prior(found) iterator
+ return_begin_found, // [begin, found) range (*)
+ return_begin_next, // [begin, next(found)) range
+ return_begin_prior, // [begin, prior(found)) range
+ return_found_end, // [found, end) range (*)
+ return_next_end, // [next(found), end) range
+ return_prior_end, // [prior(found), end) range
+ return_begin_end // [begin, end) range
+ };
+
+ template< class SinglePassRange, range_return_value >
+ struct range_return
+ {
+ typedef boost::iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+ static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+ SinglePassRange& rng)
+ {
+ return type(found, boost::end(rng));
+ }
+ };
+
+ template< class SinglePassRange >
+ struct range_return< SinglePassRange, return_found >
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type;
+
+ static type pack(type found, SinglePassRange&)
+ {
+ return found;
+ }
+ };
+
+ template< class SinglePassRange >
+ struct range_return< SinglePassRange, return_next >
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type type;
+
+ static type pack(type found, SinglePassRange& rng)
+ {
+ return found == boost::end(rng)
+ ? found
+ : boost::next(found);
+ }
+ };
+
+ template< class BidirectionalRange >
+ struct range_return< BidirectionalRange, return_prior >
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type type;
+
+ static type pack(type found, BidirectionalRange& rng)
+ {
+ return found == boost::begin(rng)
+ ? found
+ : boost::prior(found);
+ }
+ };
+
+ template< class SinglePassRange >
+ struct range_return< SinglePassRange, return_begin_found >
+ {
+ typedef boost::iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+ static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+ SinglePassRange& rng)
+ {
+ return type(boost::begin(rng), found);
+ }
+ };
+
+ template< class SinglePassRange >
+ struct range_return< SinglePassRange, return_begin_next >
+ {
+ typedef boost::iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+ static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+ SinglePassRange& rng)
+ {
+ return type( boost::begin(rng),
+ found == boost::end(rng) ? found : boost::next(found) );
+ }
+ };
+
+ template< class BidirectionalRange >
+ struct range_return< BidirectionalRange, return_begin_prior >
+ {
+ typedef boost::iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type;
+
+ static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found,
+ BidirectionalRange& rng)
+ {
+ return type( boost::begin(rng),
+ found == boost::begin(rng) ? found : boost::prior(found) );
+ }
+ };
+
+ template< class SinglePassRange >
+ struct range_return< SinglePassRange, return_found_end >
+ {
+ typedef boost::iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+ static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+ SinglePassRange& rng)
+ {
+ return type(found, boost::end(rng));
+ }
+ };
+
+ template< class SinglePassRange >
+ struct range_return< SinglePassRange, return_next_end >
+ {
+ typedef boost::iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+ static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+ SinglePassRange& rng)
+ {
+ return type( found == boost::end(rng) ? found : boost::next(found),
+ boost::end(rng) );
+ }
+ };
+
+ template< class BidirectionalRange >
+ struct range_return< BidirectionalRange, return_prior_end >
+ {
+ typedef boost::iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type > type;
+
+ static type pack(BOOST_DEDUCED_TYPENAME range_iterator<BidirectionalRange>::type found,
+ BidirectionalRange& rng)
+ {
+ return type( found == boost::begin(rng) ? found : boost::prior(found),
+ boost::end(rng) );
+ }
+ };
+
+ template< class SinglePassRange >
+ struct range_return< SinglePassRange, return_begin_end >
+ {
+ typedef boost::iterator_range<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type > type;
+
+ static type pack(BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange>::type found,
+ SinglePassRange& rng)
+ {
+ return type(boost::begin(rng), boost::end(rng));
+ }
+ };
+
+}
+
+#endif // include guard
diff --git a/src/boost/range/detail/remove_extent.hpp b/src/boost/range/detail/remove_extent.hpp
new file mode 100644
index 0000000..68e4597
--- /dev/null
+++ b/src/boost/range/detail/remove_extent.hpp
@@ -0,0 +1,157 @@
+// Boost.Range library
+//
+// Copyright Jonathan Turkanis 2005. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#ifndef BOOST_RANGE_DETAIL_REMOVE_BOUNDS_HPP
+#define BOOST_RANGE_DETAIL_REMOVE_BOUNDS_HPP
+
+#include <boost/config.hpp> // MSVC, NO_INTRINSIC_WCHAR_T, put size_t in std.
+#include <cstddef>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+
+ template< typename Case1 = mpl::true_,
+ typename Type1 = mpl::void_,
+ typename Case2 = mpl::true_,
+ typename Type2 = mpl::void_,
+ typename Case3 = mpl::true_,
+ typename Type3 = mpl::void_,
+ typename Case4 = mpl::true_,
+ typename Type4 = mpl::void_,
+ typename Case5 = mpl::true_,
+ typename Type5 = mpl::void_,
+ typename Case6 = mpl::true_,
+ typename Type6 = mpl::void_,
+ typename Case7 = mpl::true_,
+ typename Type7 = mpl::void_,
+ typename Case8 = mpl::true_,
+ typename Type8 = mpl::void_,
+ typename Case9 = mpl::true_,
+ typename Type9 = mpl::void_,
+ typename Case10 = mpl::true_,
+ typename Type10 = mpl::void_,
+ typename Case11 = mpl::true_,
+ typename Type11 = mpl::void_,
+ typename Case12 = mpl::true_,
+ typename Type12 = mpl::void_,
+ typename Case13 = mpl::true_,
+ typename Type13 = mpl::void_,
+ typename Case14 = mpl::true_,
+ typename Type14 = mpl::void_,
+ typename Case15 = mpl::true_,
+ typename Type15 = mpl::void_,
+ typename Case16 = mpl::true_,
+ typename Type16 = mpl::void_,
+ typename Case17 = mpl::true_,
+ typename Type17 = mpl::void_,
+ typename Case18 = mpl::true_,
+ typename Type18 = mpl::void_,
+ typename Case19 = mpl::true_,
+ typename Type19 = mpl::void_,
+ typename Case20 = mpl::true_,
+ typename Type20 = mpl::void_>
+ struct select {
+ typedef typename
+ mpl::eval_if<
+ Case1, mpl::identity<Type1>, mpl::eval_if<
+ Case2, mpl::identity<Type2>, mpl::eval_if<
+ Case3, mpl::identity<Type3>, mpl::eval_if<
+ Case4, mpl::identity<Type4>, mpl::eval_if<
+ Case5, mpl::identity<Type5>, mpl::eval_if<
+ Case6, mpl::identity<Type6>, mpl::eval_if<
+ Case7, mpl::identity<Type7>, mpl::eval_if<
+ Case8, mpl::identity<Type8>, mpl::eval_if<
+ Case9, mpl::identity<Type9>, mpl::if_<
+ Case10, Type10, mpl::void_ > > > > > > > > >
+ >::type result1;
+ typedef typename
+ mpl::eval_if<
+ Case11, mpl::identity<Type11>, mpl::eval_if<
+ Case12, mpl::identity<Type12>, mpl::eval_if<
+ Case13, mpl::identity<Type13>, mpl::eval_if<
+ Case14, mpl::identity<Type14>, mpl::eval_if<
+ Case15, mpl::identity<Type15>, mpl::eval_if<
+ Case16, mpl::identity<Type16>, mpl::eval_if<
+ Case17, mpl::identity<Type17>, mpl::eval_if<
+ Case18, mpl::identity<Type18>, mpl::eval_if<
+ Case19, mpl::identity<Type19>, mpl::if_<
+ Case20, Type20, mpl::void_ > > > > > > > > >
+ > result2;
+ typedef typename
+ mpl::eval_if<
+ is_same<result1, mpl::void_>,
+ result2,
+ mpl::identity<result1>
+ >::type type;
+ };
+
+ template<typename T>
+ struct remove_extent {
+ static T* ar;
+ BOOST_STATIC_CONSTANT(std::size_t, size = sizeof(*ar) / sizeof((*ar)[0]));
+
+ typedef typename
+ select<
+ is_same<T, bool[size]>, bool,
+ is_same<T, char[size]>, char,
+ is_same<T, signed char[size]>, signed char,
+ is_same<T, unsigned char[size]>, unsigned char,
+ #ifndef BOOST_NO_INTRINSIC_WCHAR_T
+ is_same<T, wchar_t[size]>, wchar_t,
+ #endif
+ is_same<T, short[size]>, short,
+ is_same<T, unsigned short[size]>, unsigned short,
+ is_same<T, int[size]>, int,
+ is_same<T, unsigned int[size]>, unsigned int,
+ is_same<T, long[size]>, long,
+ is_same<T, unsigned long[size]>, unsigned long,
+ is_same<T, float[size]>, float,
+ is_same<T, double[size]>, double,
+ is_same<T, long double[size]>, long double
+ >::type result1;
+ typedef typename
+ select<
+ is_same<T, const bool[size]>, const bool,
+ is_same<T, const char[size]>, const char,
+ is_same<T, const signed char[size]>, const signed char,
+ is_same<T, const unsigned char[size]>, const unsigned char,
+ #ifndef BOOST_NO_INTRINSIC_WCHAR_T
+ is_same<T, const wchar_t[size]>, const wchar_t,
+ #endif
+ is_same<T, const short[size]>, const short,
+ is_same<T, const unsigned short[size]>, const unsigned short,
+ is_same<T, const int[size]>, const int,
+ is_same<T, const unsigned int[size]>, const unsigned int,
+ is_same<T, const long[size]>, const long,
+ is_same<T, const unsigned long[size]>, const unsigned long,
+ is_same<T, const float[size]>, const float,
+ is_same<T, const double[size]>, const double,
+ is_same<T, const long double[size]>, const long double
+ > result2;
+ typedef typename
+ mpl::eval_if<
+ is_same<result1, mpl::void_>,
+ result2,
+ mpl::identity<result1>
+ >::type type;
+ };
+
+ } // namespace 'range_detail'
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/src/boost/range/detail/safe_bool.hpp b/src/boost/range/detail/safe_bool.hpp
new file mode 100644
index 0000000..182e510
--- /dev/null
+++ b/src/boost/range/detail/safe_bool.hpp
@@ -0,0 +1,72 @@
+// This header intentionally has no include guards.
+//
+// Copyright (c) 2010 Neil Groves
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+// This code utilises the experience gained during the evolution of
+// <boost/smart_ptr/operator_bool.hpp>
+#ifndef BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
+#define BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP
+
+#include <boost/config.hpp>
+#include <boost/range/config.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+
+template<class DataMemberPtr>
+class safe_bool
+{
+public:
+ typedef safe_bool this_type;
+
+#if (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570)) || defined(__CINT_)
+ typedef bool unspecified_bool_type;
+ static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
+ {
+ return x;
+ }
+#elif defined(_MANAGED)
+ static void unspecified_bool(this_type***)
+ {
+ }
+ typedef void(*unspecified_bool_type)(this_type***);
+ static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
+ {
+ return x ? unspecified_bool : 0;
+ }
+#elif \
+ ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
+ ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
+ ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
+
+ typedef bool (this_type::*unspecified_bool_type)() const;
+
+ static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr)
+ {
+ return x ? &this_type::detail_safe_bool_member_fn : 0;
+ }
+private:
+ bool detail_safe_bool_member_fn() const { return false; }
+#else
+ typedef DataMemberPtr unspecified_bool_type;
+ static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr p)
+ {
+ return x ? p : 0;
+ }
+#endif
+private:
+ safe_bool();
+ safe_bool(const safe_bool&);
+ void operator=(const safe_bool&);
+ ~safe_bool();
+};
+
+ } // namespace range_detail
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/detail/sfinae.hpp b/src/boost/range/detail/sfinae.hpp
new file mode 100644
index 0000000..5b2c61e
--- /dev/null
+++ b/src/boost/range/detail/sfinae.hpp
@@ -0,0 +1,77 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_SFINAE_HPP
+#define BOOST_RANGE_DETAIL_SFINAE_HPP
+
+#include <boost/range/config.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <utility>
+
+
+namespace boost
+{
+ namespace range_detail
+ {
+ using type_traits::yes_type;
+ using type_traits::no_type;
+
+ //////////////////////////////////////////////////////////////////////
+ // string
+ //////////////////////////////////////////////////////////////////////
+
+ yes_type is_string_impl( const char* const );
+ yes_type is_string_impl( const wchar_t* const );
+ no_type is_string_impl( ... );
+
+ template< std::size_t sz >
+ yes_type is_char_array_impl( char BOOST_RANGE_ARRAY_REF()[sz] );
+ template< std::size_t sz >
+ yes_type is_char_array_impl( const char BOOST_RANGE_ARRAY_REF()[sz] );
+ no_type is_char_array_impl( ... );
+
+ template< std::size_t sz >
+ yes_type is_wchar_t_array_impl( wchar_t BOOST_RANGE_ARRAY_REF()[sz] );
+ template< std::size_t sz >
+ yes_type is_wchar_t_array_impl( const wchar_t BOOST_RANGE_ARRAY_REF()[sz] );
+ no_type is_wchar_t_array_impl( ... );
+
+ yes_type is_char_ptr_impl( char* const );
+ no_type is_char_ptr_impl( ... );
+
+ yes_type is_const_char_ptr_impl( const char* const );
+ no_type is_const_char_ptr_impl( ... );
+
+ yes_type is_wchar_t_ptr_impl( wchar_t* const );
+ no_type is_wchar_t_ptr_impl( ... );
+
+ yes_type is_const_wchar_t_ptr_impl( const wchar_t* const );
+ no_type is_const_wchar_t_ptr_impl( ... );
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template< typename Iterator >
+ yes_type is_pair_impl( const std::pair<Iterator,Iterator>* );
+ no_type is_pair_impl( ... );
+
+ //////////////////////////////////////////////////////////////////////
+ // tags
+ //////////////////////////////////////////////////////////////////////
+
+ struct char_or_wchar_t_array_tag {};
+
+ } // namespace 'range_detail'
+
+} // namespace 'boost'
+
+#endif
diff --git a/src/boost/range/detail/size.hpp b/src/boost/range/detail/size.hpp
new file mode 100644
index 0000000..fe52ba0
--- /dev/null
+++ b/src/boost/range/detail/size.hpp
@@ -0,0 +1,159 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#ifndef BOOST_RANGE_DETAIL_SIZE_HPP
+#define BOOST_RANGE_DETAIL_SIZE_HPP
+
+#include <boost/config.hpp> // BOOST_MSVC
+#include <boost/detail/workaround.hpp>
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+# include <boost/range/detail/vc6/size.hpp>
+#else
+# include <boost/range/detail/implementation_help.hpp>
+# include <boost/range/detail/size_type.hpp>
+# include <boost/range/detail/common.hpp>
+# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+# include <boost/range/detail/remove_extent.hpp>
+# endif
+# include <iterator>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_size_;
+
+ //////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_size_<std_container_>
+ {
+ template< typename C >
+ static BOOST_RANGE_DEDUCED_TYPENAME C::size_type fun( const C& c )
+ {
+ return c.size();
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_size_<std_pair_>
+ {
+ template< typename P >
+ static BOOST_RANGE_DEDUCED_TYPENAME range_size<P>::type
+ fun( const P& p )
+ {
+ return std::distance( p.first, p.second );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_size_<array_>
+ {
+ #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ template< typename T, std::size_t sz >
+ static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return sz;
+ }
+ #else
+ template<typename T>
+ static std::size_t fun(T& t)
+ {
+ return remove_extent<T>::size;
+ }
+ #endif
+ };
+
+ template<>
+ struct range_size_<char_array_>
+ {
+ template< typename T, std::size_t sz >
+ static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return boost::range_detail::array_size( boost_range_array );
+ }
+ };
+
+ template<>
+ struct range_size_<wchar_t_array_>
+ {
+ template< typename T, std::size_t sz >
+ static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
+ {
+ return boost::range_detail::array_size( boost_range_array );
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // string
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_size_<char_ptr_>
+ {
+ static std::size_t fun( const char* s )
+ {
+ return boost::range_detail::str_size( s );
+ }
+ };
+
+ template<>
+ struct range_size_<const_char_ptr_>
+ {
+ static std::size_t fun( const char* s )
+ {
+ return boost::range_detail::str_size( s );
+ }
+ };
+
+ template<>
+ struct range_size_<wchar_t_ptr_>
+ {
+ static std::size_t fun( const wchar_t* s )
+ {
+ return boost::range_detail::str_size( s );
+ }
+ };
+
+ template<>
+ struct range_size_<const_wchar_t_ptr_>
+ {
+ static std::size_t fun( const wchar_t* s )
+ {
+ return boost::range_detail::str_size( s );
+ }
+ };
+
+ } // namespace 'range_detail'
+
+
+ template< typename C >
+ BOOST_RANGE_DEDUCED_TYPENAME range_size<C>::type
+ size( const C& c )
+ {
+ return range_detail::range_size_< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
+ }
+
+} // namespace 'boost'
+
+# endif
+#endif
diff --git a/src/boost/range/detail/size_type.hpp b/src/boost/range/detail/size_type.hpp
new file mode 100644
index 0000000..78a60a4
--- /dev/null
+++ b/src/boost/range/detail/size_type.hpp
@@ -0,0 +1,55 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_SIZE_TYPE_HPP
+#define BOOST_RANGE_DETAIL_SIZE_TYPE_HPP
+
+#include <boost/range/detail/common.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_size_type_
+ {
+ template< typename C >
+ struct pts
+ {
+ typedef std::size_t type;
+ };
+ };
+
+ template<>
+ struct range_size_type_<std_container_>
+ {
+ template< typename C >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME C::size_type type;
+ };
+ };
+ }
+
+ template< typename C >
+ class range_size
+ {
+ typedef typename range_detail::range<C>::type c_type;
+ public:
+ typedef typename range_detail::range_size_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
+ };
+}
+
+#endif
+
diff --git a/src/boost/range/detail/sizer.hpp b/src/boost/range/detail/sizer.hpp
new file mode 100644
index 0000000..b4c1c91
--- /dev/null
+++ b/src/boost/range/detail/sizer.hpp
@@ -0,0 +1,35 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_SIZER_HPP
+#define BOOST_RANGE_DETAIL_SIZER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <cstddef>
+
+namespace boost
+{
+ //////////////////////////////////////////////////////////////////////
+ // constant array size
+ //////////////////////////////////////////////////////////////////////
+
+ template< typename T, std::size_t sz >
+ char (& sizer( const T BOOST_RANGE_ARRAY_REF()[sz] ) )[sz];
+
+ template< typename T, std::size_t sz >
+ char (& sizer( T BOOST_RANGE_ARRAY_REF()[sz] ) )[sz];
+
+} // namespace 'boost'
+
+#endif
diff --git a/src/boost/range/detail/str_types.hpp b/src/boost/range/detail/str_types.hpp
new file mode 100644
index 0000000..f8cab19
--- /dev/null
+++ b/src/boost/range/detail/str_types.hpp
@@ -0,0 +1,38 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_STR_TYPES_HPP
+#define BOOST_RANGE_DETAIL_STR_TYPES_HPP
+
+#include <boost/range/size_type.hpp>
+#include <boost/range/iterator.hpp>
+
+namespace boost
+{
+ template< class T >
+ struct range_mutable_iterator<T*>
+ {
+ typedef T* type;
+ };
+
+ template< class T >
+ struct range_const_iterator<T*>
+ {
+ typedef const T* type;
+ };
+
+ template< class T >
+ struct range_size<T*>
+ {
+ typedef std::size_t type;
+ };
+}
+
+#endif
diff --git a/src/boost/range/detail/value_type.hpp b/src/boost/range/detail/value_type.hpp
new file mode 100644
index 0000000..2784514
--- /dev/null
+++ b/src/boost/range/detail/value_type.hpp
@@ -0,0 +1,72 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_VALUE_TYPE_HPP
+#define BOOST_RANGE_DETAIL_VALUE_TYPE_HPP
+
+#include <boost/range/detail/common.hpp>
+#include <boost/range/detail/remove_extent.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// missing partial specialization workaround.
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_value_type_;
+
+ template<>
+ struct range_value_type_<std_container_>
+ {
+ template< typename C >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME C::value_type type;
+ };
+ };
+
+ template<>
+ struct range_value_type_<std_pair_>
+ {
+ template< typename P >
+ struct pts
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_value< BOOST_RANGE_DEDUCED_TYPENAME P::first_type >::type type;
+ };
+ };
+
+ template<>
+ struct range_value_type_<array_>
+ {
+ template< typename T >
+ struct pts
+ {
+ typedef BOOST_DEDUCED_TYPENAME remove_extent<T>::type type;
+ };
+ };
+
+ }
+
+ template< typename C >
+ class range_value
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
+ public:
+ typedef BOOST_DEDUCED_TYPENAME range_detail::range_value_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
+ };
+
+}
+
+#endif
+
diff --git a/src/boost/range/detail/vc6/end.hpp b/src/boost/range/detail/vc6/end.hpp
new file mode 100644
index 0000000..4f76af5
--- /dev/null
+++ b/src/boost/range/detail/vc6/end.hpp
@@ -0,0 +1,170 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DETAIL_VC6_END_HPP
+#define BOOST_RANGE_DETAIL_VC6_END_HPP
+
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/range/result_iterator.hpp>
+#include <boost/range/detail/common.hpp>
+#include <boost/range/detail/remove_extent.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_end;
+
+ //////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_end<std_container_>
+ {
+ template< typename C >
+ struct inner {
+ static BOOST_RANGE_DEDUCED_TYPENAME range_result_iterator<C>::type
+ fun( C& c )
+ {
+ return c.end();
+ };
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_end<std_pair_>
+ {
+ template< typename P >
+ struct inner {
+ static BOOST_RANGE_DEDUCED_TYPENAME range_result_iterator<P>::type
+ fun( const P& p )
+ {
+ return p.second;
+ }
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_end<array_>
+ {
+ template< typename T >
+ struct inner {
+ static BOOST_DEDUCED_TYPENAME remove_extent<T>::type*
+ fun(T& t)
+ {
+ return t + remove_extent<T>::size;
+ }
+ };
+ };
+
+
+ template<>
+ struct range_end<char_array_>
+ {
+ template< typename T >
+ struct inner {
+ static BOOST_DEDUCED_TYPENAME remove_extent<T>::type*
+ fun(T& t)
+ {
+ return t + remove_extent<T>::size;
+ }
+ };
+ };
+
+ template<>
+ struct range_end<wchar_t_array_>
+ {
+ template< typename T >
+ struct inner {
+ static BOOST_DEDUCED_TYPENAME remove_extent<T>::type*
+ fun(T& t)
+ {
+ return t + remove_extent<T>::size;
+ }
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // string
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_end<char_ptr_>
+ {
+ template< typename T >
+ struct inner {
+ static char* fun( char* s )
+ {
+ return boost::range_detail::str_end( s );
+ }
+ };
+ };
+
+ template<>
+ struct range_end<const_char_ptr_>
+ {
+ template< typename T >
+ struct inner {
+ static const char* fun( const char* s )
+ {
+ return boost::range_detail::str_end( s );
+ }
+ };
+ };
+
+ template<>
+ struct range_end<wchar_t_ptr_>
+ {
+ template< typename T >
+ struct inner {
+ static wchar_t* fun( wchar_t* s )
+ {
+ return boost::range_detail::str_end( s );
+ }
+ };
+ };
+
+
+ template<>
+ struct range_end<const_wchar_t_ptr_>
+ {
+ template< typename T >
+ struct inner {
+ static const wchar_t* fun( const wchar_t* s )
+ {
+ return boost::range_detail::str_end( s );
+ }
+ };
+ };
+
+ } // namespace 'range_detail'
+
+ template< typename C >
+ inline BOOST_DEDUCED_TYPENAME range_result_iterator<C>::type
+ end( C& c )
+ {
+ return range_detail::range_end<range_detail::range<C>::type>::inner<C>::fun( c );
+ }
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/src/boost/range/detail/vc6/size.hpp b/src/boost/range/detail/vc6/size.hpp
new file mode 100644
index 0000000..39f559f
--- /dev/null
+++ b/src/boost/range/detail/vc6/size.hpp
@@ -0,0 +1,166 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+
+#ifndef BOOST_RANGE_DETAIL_VC6_SIZE_HPP
+#define BOOST_RANGE_DETAIL_VC6_SIZE_HPP
+
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/range/detail/size_type.hpp>
+#include <boost/range/detail/common.hpp>
+#include <boost/range/detail/remove_extent.hpp>
+#include <iterator>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template< typename T >
+ struct range_size_;
+
+ //////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_size_<std_container_>
+ {
+ template< typename C >
+ struct inner {
+ static BOOST_RANGE_DEDUCED_TYPENAME C::size_type fun( const C& c )
+ {
+ return c.size();
+ };
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_size_<std_pair_>
+ {
+ template< typename P >
+ struct inner {
+ static BOOST_RANGE_DEDUCED_TYPENAME range_size<P>::type
+ fun( const P& p )
+ {
+ return std::distance( p.first, p.second );
+ }
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_size_<array_>
+ {
+ template<typename T>
+ struct inner {
+ static std::size_t fun(T& t)
+ {
+ return remove_extent<T>::size;
+ }
+ };
+ };
+
+ template<>
+ struct range_size_<char_array_>
+ {
+ template<typename T>
+ struct inner {
+ static std::size_t fun(T& t)
+ {
+ return sizeof(T) / sizeof(T[0]);
+ }
+ };
+ };
+
+ template<>
+ struct range_size_<wchar_t_array_>
+ {
+ template<typename T>
+ struct inner {
+ static std::size_t fun(T& t)
+ {
+ return sizeof(T) / sizeof(T[0]);
+ }
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ // string
+ //////////////////////////////////////////////////////////////////////
+
+ template<>
+ struct range_size_<char_ptr_>
+ {
+ template<typename T>
+ struct inner {
+ static std::size_t fun( const char* s )
+ {
+ return boost::range_detail::str_size( s );
+ }
+ };
+ };
+
+ template<>
+ struct range_size_<const_char_ptr_>
+ {
+ template<typename T>
+ struct inner {
+ static std::size_t fun( const char* s )
+ {
+ return boost::range_detail::str_size( s );
+ }
+ };
+ };
+
+ template<>
+ struct range_size_<wchar_t_ptr_>
+ {
+ template<typename T>
+ struct inner {
+ static std::size_t fun( const wchar_t* s )
+ {
+ return boost::range_detail::str_size( s );
+ }
+ };
+ };
+
+ template<>
+ struct range_size_<const_wchar_t_ptr_>
+ {
+ template<typename T>
+ struct inner {
+ static std::size_t fun( const wchar_t* s )
+ {
+ return boost::range_detail::str_size( s );
+ }
+ };
+ };
+
+ } // namespace 'range_detail'
+
+
+ template< typename C >
+ BOOST_RANGE_DEDUCED_TYPENAME range_size<C>::type
+ size( const C& c )
+ {
+ return range_detail::range_size_<range_detail::range<C>::type>::inner<C>::fun( c );
+ }
+
+} // namespace 'boost'
+
+
+#endif
diff --git a/src/boost/range/difference_type.hpp b/src/boost/range/difference_type.hpp
new file mode 100644
index 0000000..164288f
--- /dev/null
+++ b/src/boost/range/difference_type.hpp
@@ -0,0 +1,29 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DIFFERENCE_TYPE_HPP
+#define BOOST_RANGE_DIFFERENCE_TYPE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+ template< class T >
+ struct range_difference : iterator_difference< typename range_iterator<T>::type >
+ { };
+}
+
+#endif
diff --git a/src/boost/range/distance.hpp b/src/boost/range/distance.hpp
new file mode 100644
index 0000000..42a106d
--- /dev/null
+++ b/src/boost/range/distance.hpp
@@ -0,0 +1,34 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_DISTANCE_HPP
+#define BOOST_RANGE_DISTANCE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/difference_type.hpp>
+
+namespace boost
+{
+
+ template< class T >
+ inline BOOST_DEDUCED_TYPENAME range_difference<T>::type
+ distance( const T& r )
+ {
+ return std::distance( boost::begin( r ), boost::end( r ) );
+ }
+
+} // namespace 'boost'
+
+#endif
diff --git a/src/boost/range/empty.hpp b/src/boost/range/empty.hpp
new file mode 100644
index 0000000..78c4e85
--- /dev/null
+++ b/src/boost/range/empty.hpp
@@ -0,0 +1,34 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_EMPTY_HPP
+#define BOOST_RANGE_EMPTY_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+
+namespace boost
+{
+
+ template< class T >
+ inline bool empty( const T& r )
+ {
+ return boost::begin( r ) == boost::end( r );
+ }
+
+} // namepace 'boost'
+
+
+#endif
diff --git a/src/boost/range/end.hpp b/src/boost/range/end.hpp
new file mode 100644
index 0000000..d5e6526
--- /dev/null
+++ b/src/boost/range/end.hpp
@@ -0,0 +1,136 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_END_HPP
+#define BOOST_RANGE_END_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+#include <boost/range/detail/end.hpp>
+#else
+
+#include <boost/range/detail/implementation_help.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/const_iterator.hpp>
+
+namespace boost
+{
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+namespace range_detail
+{
+#endif
+
+ //////////////////////////////////////////////////////////////////////
+ // primary template
+ //////////////////////////////////////////////////////////////////////
+ template< typename C >
+ inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
+ range_end( C& c )
+ {
+ //
+ // If you get a compile-error here, it is most likely because
+ // you have not implemented range_begin() properly in
+ // the namespace of C
+ //
+ return c.end();
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////
+
+ template< typename Iterator >
+ inline Iterator range_end( const std::pair<Iterator,Iterator>& p )
+ {
+ return p.second;
+ }
+
+ template< typename Iterator >
+ inline Iterator range_end( std::pair<Iterator,Iterator>& p )
+ {
+ return p.second;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////
+
+ template< typename T, std::size_t sz >
+ inline const T* range_end( const T (&a)[sz] )
+ {
+ return range_detail::array_end<T,sz>( a );
+ }
+
+ template< typename T, std::size_t sz >
+ inline T* range_end( T (&a)[sz] )
+ {
+ return range_detail::array_end<T,sz>( a );
+ }
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+} // namespace 'range_detail'
+#endif
+
+namespace range_adl_barrier
+{
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
+{
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+ using namespace range_detail;
+#endif
+ return range_end( r );
+}
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r )
+{
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+ using namespace range_detail;
+#endif
+ return range_end( r );
+}
+
+ } // namespace range_adl_barrier
+} // namespace 'boost'
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+namespace boost
+{
+ namespace range_adl_barrier
+ {
+ template< class T >
+ inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
+ const_end( const T& r )
+ {
+ return boost::range_adl_barrier::end( r );
+ }
+ } // namespace range_adl_barrier
+ using namespace range_adl_barrier;
+} // namespace boost
+
+#endif
+
diff --git a/src/boost/range/functions.hpp b/src/boost/range/functions.hpp
new file mode 100644
index 0000000..b8b8608
--- /dev/null
+++ b/src/boost/range/functions.hpp
@@ -0,0 +1,27 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_FUNCTIONS_HPP
+#define BOOST_RANGE_FUNCTIONS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/size.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/empty.hpp>
+#include <boost/range/rbegin.hpp>
+#include <boost/range/rend.hpp>
+
+#endif
+
diff --git a/src/boost/range/has_range_iterator.hpp b/src/boost/range/has_range_iterator.hpp
new file mode 100644
index 0000000..8046eb4
--- /dev/null
+++ b/src/boost/range/has_range_iterator.hpp
@@ -0,0 +1,62 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
+#define BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
+
+ template<class T, class Enabler = void>
+ struct has_range_iterator_impl
+ : boost::mpl::false_
+ {
+ };
+
+ template<class T>
+ struct has_range_iterator_impl<T, BOOST_DEDUCED_TYPENAME enable_if< has_type< range_mutable_iterator<T> > >::type>
+ : boost::mpl::true_
+ {
+ };
+
+ template<class T, class Enabler = void>
+ struct has_range_const_iterator_impl
+ : boost::mpl::false_
+ {
+ };
+
+ template<class T>
+ struct has_range_const_iterator_impl<T, BOOST_DEDUCED_TYPENAME enable_if< has_type< range_const_iterator<T> > >::type>
+ : boost::mpl::true_
+ {
+ };
+
+ } // namespace range_detail
+
+ template<class T>
+ struct has_range_iterator
+ : range_detail::has_range_iterator_impl<T>
+ {};
+
+ template<class T>
+ struct has_range_const_iterator
+ : range_detail::has_range_const_iterator_impl<T>
+ {};
+} // namespace boost
+
+#endif // include guard
+
diff --git a/src/boost/range/irange.hpp b/src/boost/range/irange.hpp
new file mode 100644
index 0000000..3b5a6cc
--- /dev/null
+++ b/src/boost/range/irange.hpp
@@ -0,0 +1,230 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_IRANGE_HPP_INCLUDED
+#define BOOST_RANGE_IRANGE_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ // integer_iterator is an iterator over an integer sequence that
+ // is bounded only by the limits of the underlying integer
+ // representation.
+ //
+ // This is useful for implementing the irange(first, last)
+ // function.
+ //
+ // Note:
+ // This use of this iterator and irange is appreciably less
+ // performant than the corresponding hand-written integer
+ // loop on many compilers.
+ template<typename Integer>
+ class integer_iterator
+ : public boost::iterator_facade<
+ integer_iterator<Integer>,
+ Integer,
+ boost::random_access_traversal_tag,
+ Integer,
+ std::ptrdiff_t
+ >
+ {
+ typedef boost::iterator_facade<
+ integer_iterator<Integer>,
+ Integer,
+ boost::random_access_traversal_tag,
+ Integer,
+ std::ptrdiff_t
+ > base_t;
+ public:
+ typedef typename base_t::value_type value_type;
+ typedef typename base_t::difference_type difference_type;
+ typedef typename base_t::reference reference;
+
+ integer_iterator() : m_value() {}
+ explicit integer_iterator(value_type x) : m_value(x) {}
+
+ private:
+ void increment()
+ {
+ ++m_value;
+ }
+
+ void decrement()
+ {
+ --m_value;
+ }
+
+ void advance(difference_type offset)
+ {
+ m_value += offset;
+ }
+
+ difference_type distance_to(const integer_iterator& other) const
+ {
+ return other.m_value - m_value;
+ }
+
+ bool equal(const integer_iterator& other) const
+ {
+ return m_value == other.m_value;
+ }
+
+ reference dereference() const
+ {
+ return m_value;
+ }
+
+ friend class ::boost::iterator_core_access;
+ value_type m_value;
+ };
+
+ // integer_iterator_with_step is similar in nature to the
+ // integer_iterator but provides the ability to 'move' in
+ // a number of steps specified at construction time.
+ //
+ // The three variable implementation provides the best guarantees
+ // of loop termination upon various combinations of input.
+ //
+ // While this design is less performant than some less
+ // safe alternatives, the use of ranges and iterators to
+ // perform counting will never be optimal anyhow, hence
+ // if optimal performance is desired a handcoded loop
+ // is the solution.
+ template<typename Integer>
+ class integer_iterator_with_step
+ : public boost::iterator_facade<
+ integer_iterator_with_step<Integer>,
+ Integer,
+ boost::random_access_traversal_tag,
+ Integer,
+ std::ptrdiff_t
+ >
+ {
+ typedef boost::iterator_facade<
+ integer_iterator_with_step<Integer>,
+ Integer,
+ boost::random_access_traversal_tag,
+ Integer,
+ std::ptrdiff_t
+ > base_t;
+ public:
+ typedef typename base_t::value_type value_type;
+ typedef typename base_t::difference_type difference_type;
+ typedef typename base_t::reference reference;
+
+ integer_iterator_with_step(value_type first, difference_type step, value_type step_size)
+ : m_first(first)
+ , m_step(step)
+ , m_step_size(step_size)
+ {
+ }
+
+ private:
+ void increment()
+ {
+ ++m_step;
+ }
+
+ void decrement()
+ {
+ --m_step;
+ }
+
+ void advance(difference_type offset)
+ {
+ m_step += offset;
+ }
+
+ difference_type distance_to(const integer_iterator_with_step& other) const
+ {
+ return other.m_step - m_step;
+ }
+
+ bool equal(const integer_iterator_with_step& other) const
+ {
+ return m_step == other.m_step;
+ }
+
+ reference dereference() const
+ {
+ return m_first + (m_step * m_step_size);
+ }
+
+ friend class ::boost::iterator_core_access;
+ value_type m_first;
+ value_type m_step;
+ difference_type m_step_size;
+ };
+
+ } // namespace range_detail
+
+ template<typename Integer>
+ class integer_range
+ : public iterator_range< range_detail::integer_iterator<Integer> >
+ {
+ typedef range_detail::integer_iterator<Integer> iterator_t;
+ typedef iterator_range<iterator_t> base_t;
+ public:
+ integer_range(Integer first, Integer last)
+ : base_t(iterator_t(first), iterator_t(last))
+ {
+ }
+ };
+
+ template<typename Integer>
+ class strided_integer_range
+ : public iterator_range< range_detail::integer_iterator_with_step<Integer> >
+ {
+ typedef range_detail::integer_iterator_with_step<Integer> iterator_t;
+ typedef iterator_range<iterator_t> base_t;
+ public:
+ template<typename Iterator>
+ strided_integer_range(Iterator first, Iterator last)
+ : base_t(first, last)
+ {
+ }
+ };
+
+ template<typename Integer>
+ integer_range<Integer>
+ irange(Integer first, Integer last)
+ {
+ BOOST_ASSERT( first <= last );
+ return integer_range<Integer>(first, last);
+ }
+
+ template<typename Integer, typename StepSize>
+ strided_integer_range<Integer>
+ irange(Integer first, Integer last, StepSize step_size)
+ {
+ BOOST_ASSERT( step_size != 0 );
+ BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) );
+
+ typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t;
+
+ const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step_size >= 0 ? step_size : -step_size);
+ const Integer l = step_size >= 0 ? last : first;
+ const Integer f = step_size >= 0 ? first : last;
+ const std::ptrdiff_t num_steps = (l + ((l-f) % sz) - f) / sz;
+ BOOST_ASSERT(num_steps >= 0);
+
+ return strided_integer_range<Integer>(
+ iterator_t(first, 0, step_size),
+ iterator_t(first, num_steps, step_size));
+ }
+
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/istream_range.hpp b/src/boost/range/istream_range.hpp
new file mode 100644
index 0000000..c3f2248
--- /dev/null
+++ b/src/boost/range/istream_range.hpp
@@ -0,0 +1,37 @@
+// Copyright Neil Groves 2010. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ISTREAM_RANGE_HPP_INCLUDED
+
+/*!
+ * \file istream_range.hpp
+ */
+
+#include <iterator>
+#include <istream>
+#include <boost/config.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+ namespace range
+ {
+ template<class Type, class Elem, class Traits> inline
+ iterator_range<std::istream_iterator<Type, Elem, Traits> >
+ istream_range(std::basic_istream<Elem, Traits>& in)
+ {
+ return iterator_range<std::istream_iterator<Type, Elem, Traits> >(
+ std::istream_iterator<Type>(in),
+ std::istream_iterator<Type>());
+ }
+ } // namespace range
+ using range::istream_range;
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/iterator.hpp b/src/boost/range/iterator.hpp
new file mode 100644
index 0000000..ec73ddc
--- /dev/null
+++ b/src/boost/range/iterator.hpp
@@ -0,0 +1,72 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_ITERATOR_HPP
+#define BOOST_RANGE_ITERATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/mutable_iterator.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/mpl/eval_if.hpp>
+
+namespace boost
+{
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+
+ namespace range_detail_vc7_1
+ {
+ template< typename C, typename Sig = void(C) >
+ struct range_iterator
+ {
+ typedef BOOST_RANGE_DEDUCED_TYPENAME
+ mpl::eval_if_c< is_const<C>::value,
+ range_const_iterator< typename remove_const<C>::type >,
+ range_mutable_iterator<C> >::type type;
+ };
+
+ template< typename C, typename T >
+ struct range_iterator< C, void(T[]) >
+ {
+ typedef T* type;
+ };
+ }
+
+#endif
+
+ template< typename C >
+ struct range_iterator
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+
+ typedef BOOST_RANGE_DEDUCED_TYPENAME
+ range_detail_vc7_1::range_iterator<C>::type type;
+
+#else
+
+ typedef BOOST_RANGE_DEDUCED_TYPENAME
+ mpl::eval_if_c< is_const<C>::value,
+ range_const_iterator< typename remove_const<C>::type >,
+ range_mutable_iterator<C> >::type type;
+
+#endif
+ };
+
+} // namespace boost
+
+//#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#endif
diff --git a/src/boost/range/iterator_range.hpp b/src/boost/range/iterator_range.hpp
new file mode 100644
index 0000000..dfcd4d2
--- /dev/null
+++ b/src/boost/range/iterator_range.hpp
@@ -0,0 +1,16 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009.
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ITERATOR_RANGE_HPP_INCLUDED
+#define BOOST_RANGE_ITERATOR_RANGE_HPP_INCLUDED
+
+#include "boost/range/iterator_range_core.hpp"
+#include "boost/range/iterator_range_io.hpp"
+
+#endif // include guard
diff --git a/src/boost/range/iterator_range_core.hpp b/src/boost/range/iterator_range_core.hpp
new file mode 100644
index 0000000..60c7670
--- /dev/null
+++ b/src/boost/range/iterator_range_core.hpp
@@ -0,0 +1,650 @@
+// Boost.Range library
+//
+// Copyright Neil Groves & Thorsten Ottosen & Pavol Droba 2003-2004.
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
+#define BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED
+
+#include <boost/config.hpp> // Define __STL_CONFIG_H, if appropriate.
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ #pragma warning( push )
+ #pragma warning( disable : 4996 )
+#endif
+
+#include <boost/assert.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/type_traits/is_abstract.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/algorithm/equal.hpp>
+#include <boost/range/detail/safe_bool.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <iterator>
+#include <algorithm>
+#include <cstddef>
+
+/*! \file
+ Defines the \c iterator_class and related functions.
+ \c iterator_range is a simple wrapper of iterator pair idiom. It provides
+ a rich subset of Container interface.
+*/
+
+
+namespace boost
+{
+ namespace iterator_range_detail
+ {
+ //
+ // The functions adl_begin and adl_end are implemented in a separate
+ // class for gcc-2.9x
+ //
+ template<class IteratorT>
+ struct iterator_range_impl {
+ template< class ForwardRange >
+ static IteratorT adl_begin( ForwardRange& r )
+ {
+ return static_cast<IteratorT>( boost::begin( r ) );
+ }
+
+ template< class ForwardRange >
+ static IteratorT adl_end( ForwardRange& r )
+ {
+ return static_cast<IteratorT>( boost::end( r ) );
+ }
+ };
+
+ template< class Left, class Right >
+ inline bool less_than( const Left& l, const Right& r )
+ {
+ return std::lexicographical_compare( boost::begin(l),
+ boost::end(l),
+ boost::begin(r),
+ boost::end(r) );
+ }
+
+ template< class Left, class Right >
+ inline bool greater_than( const Left& l, const Right& r )
+ {
+ return less_than(r,l);
+ }
+
+ template< class Left, class Right >
+ inline bool less_or_equal_than( const Left& l, const Right& r )
+ {
+ return !iterator_range_detail::less_than(r,l);
+ }
+
+ template< class Left, class Right >
+ inline bool greater_or_equal_than( const Left& l, const Right& r )
+ {
+ return !iterator_range_detail::less_than(l,r);
+ }
+
+ // This version is maintained since it is used in other boost libraries
+ // such as Boost.Assign
+ template< class Left, class Right >
+ inline bool equal(const Left& l, const Right& r)
+ {
+ return boost::equal(l, r);
+ }
+
+ struct range_tag { };
+ struct const_range_tag { };
+ }
+
+// iterator range template class -----------------------------------------//
+
+ //! iterator_range class
+ /*!
+ An \c iterator_range delimits a range in a sequence by beginning and ending iterators.
+ An iterator_range can be passed to an algorithm which requires a sequence as an input.
+ For example, the \c toupper() function may be used most frequently on strings,
+ but can also be used on iterator_ranges:
+
+ \code
+ boost::tolower( find( s, "UPPERCASE STRING" ) );
+ \endcode
+
+ Many algorithms working with sequences take a pair of iterators,
+ delimiting a working range, as an arguments. The \c iterator_range class is an
+ encapsulation of a range identified by a pair of iterators.
+ It provides a collection interface,
+ so it is possible to pass an instance to an algorithm requiring a collection as an input.
+ */
+ template<class IteratorT>
+ class iterator_range
+ {
+ typedef range_detail::safe_bool< IteratorT iterator_range<IteratorT>::* > safe_bool_t;
+ protected: // Used by sub_range
+ //! implementation class
+ typedef iterator_range_detail::iterator_range_impl<IteratorT> impl;
+ public:
+ //! this type
+ typedef iterator_range<IteratorT> type;
+ typedef BOOST_DEDUCED_TYPENAME safe_bool_t::unspecified_bool_type unspecified_bool_type;
+ //BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(value_type);
+
+ //! Encapsulated value type
+ typedef BOOST_DEDUCED_TYPENAME
+ iterator_value<IteratorT>::type value_type;
+
+ //! Difference type
+ typedef BOOST_DEDUCED_TYPENAME
+ iterator_difference<IteratorT>::type difference_type;
+
+ //! Size type
+ typedef std::size_t size_type; // note: must be unsigned
+
+ //! This type
+ typedef iterator_range<IteratorT> this_type;
+
+ //! Reference type
+ //
+ // Needed because value-type is the same for
+ // const and non-const iterators
+ //
+ typedef BOOST_DEDUCED_TYPENAME
+ iterator_reference<IteratorT>::type reference;
+
+ //! const_iterator type
+ /*!
+ There is no distinction between const_iterator and iterator.
+ These typedefs are provides to fulfill container interface
+ */
+ typedef IteratorT const_iterator;
+ //! iterator type
+ typedef IteratorT iterator;
+
+ private: // for return value of operator()()
+ typedef BOOST_DEDUCED_TYPENAME
+ boost::mpl::if_< boost::is_abstract<value_type>,
+ reference, value_type >::type abstract_value_type;
+
+ public:
+ iterator_range() : m_Begin( iterator() ), m_End( iterator() )
+ { }
+
+ //! Constructor from a pair of iterators
+ template< class Iterator >
+ iterator_range( Iterator Begin, Iterator End ) :
+ m_Begin(Begin), m_End(End)
+ {}
+
+ //! Constructor from a Range
+ template< class Range >
+ iterator_range( const Range& r ) :
+ m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
+ {}
+
+ //! Constructor from a Range
+ template< class Range >
+ iterator_range( Range& r ) :
+ m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
+ {}
+
+ //! Constructor from a Range
+ template< class Range >
+ iterator_range( const Range& r, iterator_range_detail::const_range_tag ) :
+ m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
+ {}
+
+ //! Constructor from a Range
+ template< class Range >
+ iterator_range( Range& r, iterator_range_detail::range_tag ) :
+ m_Begin( impl::adl_begin( r ) ), m_End( impl::adl_end( r ) )
+ {}
+
+ #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+ this_type& operator=( const this_type& r )
+ {
+ m_Begin = r.begin();
+ m_End = r.end();
+ return *this;
+ }
+ #endif
+
+ template< class Iterator >
+ iterator_range& operator=( const iterator_range<Iterator>& r )
+ {
+ m_Begin = r.begin();
+ m_End = r.end();
+ return *this;
+ }
+
+ template< class ForwardRange >
+ iterator_range& operator=( ForwardRange& r )
+ {
+ m_Begin = impl::adl_begin( r );
+ m_End = impl::adl_end( r );
+ return *this;
+ }
+
+ template< class ForwardRange >
+ iterator_range& operator=( const ForwardRange& r )
+ {
+ m_Begin = impl::adl_begin( r );
+ m_End = impl::adl_end( r );
+ return *this;
+ }
+
+ IteratorT begin() const
+ {
+ return m_Begin;
+ }
+
+ IteratorT end() const
+ {
+ return m_End;
+ }
+
+ difference_type size() const
+ {
+ return m_End - m_Begin;
+ }
+
+ bool empty() const
+ {
+ return m_Begin == m_End;
+ }
+
+ operator unspecified_bool_type() const
+ {
+ return safe_bool_t::to_unspecified_bool(m_Begin != m_End, &iterator_range::m_Begin);
+ }
+
+ bool operator!() const
+ {
+ return empty();
+ }
+
+ bool equal( const iterator_range& r ) const
+ {
+ return m_Begin == r.m_Begin && m_End == r.m_End;
+ }
+
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ bool operator==( const iterator_range& r ) const
+ {
+ return boost::equal( *this, r );
+ }
+
+ bool operator!=( const iterator_range& r ) const
+ {
+ return !operator==(r);
+ }
+
+ bool operator<( const iterator_range& r ) const
+ {
+ return iterator_range_detail::less_than( *this, r );
+ }
+
+ bool operator>( const iterator_range& r ) const
+ {
+ return iterator_range_detail::greater_than( *this, r );
+ }
+
+ bool operator<=( const iterator_range& r ) const
+ {
+ return iterator_range_detail::less_or_equal_than( *this, r );
+ }
+
+ bool operator>=( const iterator_range& r ) const
+ {
+ return iterator_range_detail::greater_or_equal_than( *this, r );
+ }
+
+#endif
+
+ public: // convenience
+ reference front() const
+ {
+ BOOST_ASSERT( !empty() );
+ return *m_Begin;
+ }
+
+ reference back() const
+ {
+ BOOST_ASSERT( !empty() );
+ IteratorT last( m_End );
+ return *--last;
+ }
+
+ // pop_front() - added to model the SinglePassRangePrimitiveConcept
+ void pop_front()
+ {
+ BOOST_ASSERT( !empty() );
+ ++m_Begin;
+ }
+
+ // pop_back() - added to model the BidirectionalRangePrimitiveConcept
+ void pop_back()
+ {
+ BOOST_ASSERT( !empty() );
+ --m_End;
+ }
+
+ reference operator[]( difference_type at ) const
+ {
+ BOOST_ASSERT( at >= 0 && at < size() );
+ return m_Begin[at];
+ }
+
+ //
+ // When storing transform iterators, operator[]()
+ // fails because it returns by reference. Therefore
+ // operator()() is provided for these cases.
+ //
+ abstract_value_type operator()( difference_type at ) const
+ {
+ BOOST_ASSERT( at >= 0 && at < size() );
+ return m_Begin[at];
+ }
+
+ iterator_range& advance_begin( difference_type n )
+ {
+ std::advance( m_Begin, n );
+ return *this;
+ }
+
+ iterator_range& advance_end( difference_type n )
+ {
+ std::advance( m_End, n );
+ return *this;
+ }
+
+ private:
+ // begin and end iterators
+ IteratorT m_Begin;
+ IteratorT m_End;
+
+ protected:
+ //
+ // Allow subclasses an easy way to access the
+ // base type
+ //
+ typedef iterator_range iterator_range_;
+ };
+
+// iterator range free-standing operators ---------------------------//
+
+ /////////////////////////////////////////////////////////////////////
+ // comparison operators
+ /////////////////////////////////////////////////////////////////////
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator==( const ForwardRange& l,
+ const iterator_range<IteratorT>& r )
+ {
+ return boost::equal( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator!=( const ForwardRange& l,
+ const iterator_range<IteratorT>& r )
+ {
+ return !boost::equal( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator<( const ForwardRange& l,
+ const iterator_range<IteratorT>& r )
+ {
+ return iterator_range_detail::less_than( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator<=( const ForwardRange& l,
+ const iterator_range<IteratorT>& r )
+ {
+ return iterator_range_detail::less_or_equal_than( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator>( const ForwardRange& l,
+ const iterator_range<IteratorT>& r )
+ {
+ return iterator_range_detail::greater_than( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator>=( const ForwardRange& l,
+ const iterator_range<IteratorT>& r )
+ {
+ return iterator_range_detail::greater_or_equal_than( l, r );
+ }
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+#else
+ template< class Iterator1T, class Iterator2T >
+ inline bool operator==( const iterator_range<Iterator1T>& l,
+ const iterator_range<Iterator2T>& r )
+ {
+ return boost::equal( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator==( const iterator_range<IteratorT>& l,
+ const ForwardRange& r )
+ {
+ return boost::equal( l, r );
+ }
+
+
+ template< class Iterator1T, class Iterator2T >
+ inline bool operator!=( const iterator_range<Iterator1T>& l,
+ const iterator_range<Iterator2T>& r )
+ {
+ return !boost::equal( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator!=( const iterator_range<IteratorT>& l,
+ const ForwardRange& r )
+ {
+ return !boost::equal( l, r );
+ }
+
+
+ template< class Iterator1T, class Iterator2T >
+ inline bool operator<( const iterator_range<Iterator1T>& l,
+ const iterator_range<Iterator2T>& r )
+ {
+ return iterator_range_detail::less_than( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator<( const iterator_range<IteratorT>& l,
+ const ForwardRange& r )
+ {
+ return iterator_range_detail::less_than( l, r );
+ }
+
+ template< class Iterator1T, class Iterator2T >
+ inline bool operator<=( const iterator_range<Iterator1T>& l,
+ const iterator_range<Iterator2T>& r )
+ {
+ return iterator_range_detail::less_or_equal_than( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator<=( const iterator_range<IteratorT>& l,
+ const ForwardRange& r )
+ {
+ return iterator_range_detail::less_or_equal_than( l, r );
+ }
+
+ template< class Iterator1T, class Iterator2T >
+ inline bool operator>( const iterator_range<Iterator1T>& l,
+ const iterator_range<Iterator2T>& r )
+ {
+ return iterator_range_detail::greater_than( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator>( const iterator_range<IteratorT>& l,
+ const ForwardRange& r )
+ {
+ return iterator_range_detail::greater_than( l, r );
+ }
+
+ template< class Iterator1T, class Iterator2T >
+ inline bool operator>=( const iterator_range<Iterator1T>& l,
+ const iterator_range<Iterator2T>& r )
+ {
+ return iterator_range_detail::greater_or_equal_than( l, r );
+ }
+
+ template< class IteratorT, class ForwardRange >
+ inline bool operator>=( const iterator_range<IteratorT>& l,
+ const ForwardRange& r )
+ {
+ return iterator_range_detail::greater_or_equal_than( l, r );
+ }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+// iterator range utilities -----------------------------------------//
+
+ //! iterator_range construct helper
+ /*!
+ Construct an \c iterator_range from a pair of iterators
+
+ \param Begin A begin iterator
+ \param End An end iterator
+ \return iterator_range object
+ */
+ template< typename IteratorT >
+ inline iterator_range< IteratorT >
+ make_iterator_range( IteratorT Begin, IteratorT End )
+ {
+ return iterator_range<IteratorT>( Begin, End );
+ }
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< typename Range >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+ make_iterator_range( Range& r )
+ {
+ return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+ ( boost::begin( r ), boost::end( r ) );
+ }
+
+#else
+ //! iterator_range construct helper
+ /*!
+ Construct an \c iterator_range from a \c Range containing the begin
+ and end iterators.
+ */
+ template< class ForwardRange >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
+ make_iterator_range( ForwardRange& r )
+ {
+ return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
+ ( r, iterator_range_detail::range_tag() );
+ }
+
+ template< class ForwardRange >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
+ make_iterator_range( const ForwardRange& r )
+ {
+ return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type >
+ ( r, iterator_range_detail::const_range_tag() );
+ }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ namespace iterator_range_detail
+ {
+ template< class Range >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+ make_range_impl( Range& r,
+ BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
+ BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
+ {
+ //
+ // Not worth the effort
+ //
+ //if( advance_begin == 0 && advance_end == 0 )
+ // return make_iterator_range( r );
+ //
+
+ BOOST_DEDUCED_TYPENAME range_iterator<Range>::type
+ new_begin = boost::begin( r ),
+ new_end = boost::end( r );
+ std::advance( new_begin, advance_begin );
+ std::advance( new_end, advance_end );
+ return make_iterator_range( new_begin, new_end );
+ }
+ }
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ template< class Range >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+ make_iterator_range( Range& r,
+ BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
+ BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
+ {
+ //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
+ return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
+ }
+
+#else
+
+ template< class Range >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
+ make_iterator_range( Range& r,
+ BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
+ BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
+ {
+ //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
+ return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
+ }
+
+ template< class Range >
+ inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const Range>::type >
+ make_iterator_range( const Range& r,
+ BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
+ BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
+ {
+ //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" );
+ return iterator_range_detail::make_range_impl( r, advance_begin, advance_end );
+ }
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+ //! copy a range into a sequence
+ /*!
+ Construct a new sequence of the specified type from the elements
+ in the given range
+
+ \param Range An input range
+ \return New sequence
+ */
+ template< typename SeqT, typename Range >
+ inline SeqT copy_range( const Range& r )
+ {
+ return SeqT( boost::begin( r ), boost::end( r ) );
+ }
+
+} // namespace 'boost'
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ #pragma warning( pop )
+#endif
+
+#endif
+
diff --git a/src/boost/range/iterator_range_io.hpp b/src/boost/range/iterator_range_io.hpp
new file mode 100644
index 0000000..51e3a4f
--- /dev/null
+++ b/src/boost/range/iterator_range_io.hpp
@@ -0,0 +1,93 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009.
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_ITERATOR_RANGE_IO_HPP_INCLUDED
+#define BOOST_RANGE_ITERATOR_RANGE_IO_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ #pragma warning( push )
+ #pragma warning( disable : 4996 )
+#endif
+
+// From boost/dynamic_bitset.hpp; thanks to Matthias Troyer for Cray X1 patch.
+#ifndef BOOST_OLD_IOSTREAMS
+# if defined(__STL_CONFIG_H) && \
+ !defined (__STL_USE_NEW_IOSTREAMS) && !defined(__crayx1) \
+ /**/
+# define BOOST_OLD_IOSTREAMS
+# endif
+#endif // #ifndef BOOST_OLD_IOSTREAMS
+
+#ifndef _STLP_NO_IOSTREAMS
+# ifndef BOOST_OLD_IOSTREAMS
+# include <ostream>
+# else
+# include <ostream.h>
+# endif
+#endif // _STLP_NO_IOSTREAMS
+
+#include <boost/range/iterator_range_core.hpp>
+#include <iterator>
+#include <algorithm>
+#include <cstddef>
+
+namespace boost
+{
+
+#ifndef _STLP_NO_IOSTREAMS
+# ifndef BOOST_OLD_IOSTREAMS
+
+ //! iterator_range output operator
+ /*!
+ Output the range to an ostream. Elements are outputed
+ in a sequence without separators.
+ */
+ template< typename IteratorT, typename Elem, typename Traits >
+ inline std::basic_ostream<Elem,Traits>& operator<<(
+ std::basic_ostream<Elem, Traits>& Os,
+ const iterator_range<IteratorT>& r )
+ {
+ std::copy( r.begin(), r.end(),
+ std::ostream_iterator< BOOST_DEDUCED_TYPENAME
+ iterator_value<IteratorT>::type,
+ Elem, Traits>(Os) );
+ return Os;
+ }
+
+# else
+
+ //! iterator_range output operator
+ /*!
+ Output the range to an ostream. Elements are outputed
+ in a sequence without separators.
+ */
+ template< typename IteratorT >
+ inline std::ostream& operator<<(
+ std::ostream& Os,
+ const iterator_range<IteratorT>& r )
+ {
+ std::copy( r.begin(), r.end(), std::ostream_iterator<char>(Os));
+ return Os;
+ }
+
+# endif
+#endif // _STLP_NO_IOSTREAMS
+
+} // namespace boost
+
+#undef BOOST_OLD_IOSTREAMS
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ #pragma warning(pop)
+#endif
+
+#endif // include guard
diff --git a/src/boost/range/join.hpp b/src/boost/range/join.hpp
new file mode 100644
index 0000000..aacc0a3
--- /dev/null
+++ b/src/boost/range/join.hpp
@@ -0,0 +1,91 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+#ifndef BOOST_RANGE_JOIN_HPP_INCLUDED
+#define BOOST_RANGE_JOIN_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/range/detail/join_iterator.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+
+template<class SinglePassRange1, class SinglePassRange2>
+class joined_type
+{
+public:
+ typedef iterator_range<
+ range_detail::join_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type,
+ BOOST_DEDUCED_TYPENAME range_value<SinglePassRange1>::type
+ >
+ > type;
+};
+
+ } // namespace range_detail
+
+namespace range
+{
+
+template<class SinglePassRange1, class SinglePassRange2>
+class joined_range
+ : public range_detail::joined_type<SinglePassRange1, SinglePassRange2>::type
+{
+ typedef range_detail::join_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type,
+ BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type,
+ BOOST_DEDUCED_TYPENAME range_value<SinglePassRange1>::type
+ > iterator_t;
+
+ typedef BOOST_DEDUCED_TYPENAME range_detail::joined_type<
+ SinglePassRange1, SinglePassRange2>::type base_t;
+public:
+ joined_range(SinglePassRange1& rng1, SinglePassRange2& rng2)
+ : base_t(
+ iterator_t(rng1, rng2, range_detail::join_iterator_begin_tag()),
+ iterator_t(rng1, rng2, range_detail::join_iterator_end_tag())
+ )
+ {
+ }
+};
+
+template<class SinglePassRange1, class SinglePassRange2>
+joined_range<const SinglePassRange1, const SinglePassRange2>
+join(const SinglePassRange1& r1, const SinglePassRange2& r2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return joined_range<const SinglePassRange1, const SinglePassRange2>(r1, r2);
+}
+
+template<class SinglePassRange1, class SinglePassRange2>
+joined_range<SinglePassRange1, SinglePassRange2>
+join(SinglePassRange1& r1, SinglePassRange2& r2)
+{
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> ));
+
+ return joined_range<SinglePassRange1, SinglePassRange2>(r1, r2);
+}
+
+} // namespace range
+
+using ::boost::range::joined_range;
+using ::boost::range::join;
+
+} // namespace boost
+
+#endif // include guard
diff --git a/src/boost/range/metafunctions.hpp b/src/boost/range/metafunctions.hpp
new file mode 100644
index 0000000..469d9ae
--- /dev/null
+++ b/src/boost/range/metafunctions.hpp
@@ -0,0 +1,31 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_METAFUNCTIONS_HPP
+#define BOOST_RANGE_METAFUNCTIONS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/iterator.hpp>
+#include <boost/range/has_range_iterator.hpp>
+#include <boost/range/result_iterator.hpp>
+#include <boost/range/reverse_iterator.hpp>
+#include <boost/range/const_reverse_iterator.hpp>
+#include <boost/range/reverse_result_iterator.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/category.hpp>
+#include <boost/range/reference.hpp>
+#include <boost/range/pointer.hpp>
+
+#endif
diff --git a/src/boost/range/mfc.hpp b/src/boost/range/mfc.hpp
new file mode 100644
index 0000000..058e54e
--- /dev/null
+++ b/src/boost/range/mfc.hpp
@@ -0,0 +1,984 @@
+#ifndef BOOST_RANGE_MFC_HPP
+#define BOOST_RANGE_MFC_HPP
+
+
+
+
+// Boost.Range MFC Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+
+// config
+//
+
+
+#include <afx.h> // _MFC_VER
+
+
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+ #if (_MFC_VER < 0x0700) // dubious
+ #define BOOST_RANGE_MFC_NO_CPAIR
+ #endif
+#endif
+
+
+#if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+ #if (_MFC_VER < 0x0700) // dubious
+ #define BOOST_RANGE_MFC_HAS_LEGACY_STRING
+ #endif
+#endif
+
+
+// A const collection of old MFC doesn't return const reference.
+//
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ #if (_MFC_VER < 0x0700) // dubious
+ #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF
+ #endif
+#endif
+
+
+
+
+// forward declarations
+//
+
+
+template< class Type, class ArgType >
+class CArray;
+
+template< class Type, class ArgType >
+class CList;
+
+template< class Key, class ArgKey, class Mapped, class ArgMapped >
+class CMap;
+
+template< class BaseClass, class PtrType >
+class CTypedPtrArray;
+
+template< class BaseClass, class PtrType >
+class CTypedPtrList;
+
+template< class BaseClass, class KeyPtrType, class MappedPtrType >
+class CTypedPtrMap;
+
+
+
+
+// extended customizations
+//
+
+
+#include <cstddef> // ptrdiff_t
+#include <utility> // pair
+#include <boost/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range/atl.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/detail/microsoft.hpp>
+#include <boost/range/end.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/utility/addressof.hpp>
+#include <afx.h> // legacy CString
+#include <afxcoll.h> // CXXXArray, CXXXList, CMapXXXToXXX
+#include <tchar.h>
+
+
+namespace boost { namespace range_detail_microsoft {
+
+
+ // mfc_ptr_array_iterator
+ //
+ // 'void **' is not convertible to 'void const **',
+ // so we define...
+ //
+
+ template< class ArrayT, class PtrType >
+ struct mfc_ptr_array_iterator;
+
+ template< class ArrayT, class PtrType >
+ struct mfc_ptr_array_iterator_super
+ {
+ typedef iterator_adaptor<
+ mfc_ptr_array_iterator<ArrayT, PtrType>,
+ std::ptrdiff_t, // Base!
+ PtrType, // Value
+ random_access_traversal_tag,
+ use_default,
+ std::ptrdiff_t // Difference
+ > type;
+ };
+
+ template< class ArrayT, class PtrType >
+ struct mfc_ptr_array_iterator :
+ mfc_ptr_array_iterator_super<ArrayT, PtrType>::type
+ {
+ private:
+ typedef mfc_ptr_array_iterator self_t;
+ typedef typename mfc_ptr_array_iterator_super<ArrayT, PtrType>::type super_t;
+ typedef typename super_t::reference ref_t;
+
+ public:
+ explicit mfc_ptr_array_iterator()
+ { }
+
+ explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) :
+ super_t(index), m_parr(boost::addressof(arr))
+ { }
+
+ template< class, class > friend struct mfc_ptr_array_iterator;
+ template< class ArrayT_, class PtrType_ >
+ mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) :
+ super_t(other.base()), m_parr(other.m_parr)
+ { }
+
+ private:
+ ArrayT *m_parr;
+
+ friend class iterator_core_access;
+ ref_t dereference() const
+ {
+ BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range");
+ return *( m_parr->GetData() + this->base() );
+ }
+
+ bool equal(self_t const& other) const
+ {
+ BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible");
+ return this->base() == other.base();
+ }
+ };
+
+ struct mfc_ptr_array_functions
+ {
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ return Iterator(x, 0);
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return Iterator(x, x.GetSize());
+ }
+ };
+
+
+ // arrays
+ //
+
+ template< >
+ struct customization< ::CByteArray > :
+ array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef BYTE val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CDWordArray > :
+ array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef DWORD val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CObArray > :
+ mfc_ptr_array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator;
+ typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CPtrArray > :
+ mfc_ptr_array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef mfc_ptr_array_iterator<X, void *> mutable_iterator;
+ typedef mfc_ptr_array_iterator<X const, void const *> const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CStringArray > :
+ array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef ::CString val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CUIntArray > :
+ array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef UINT val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CWordArray > :
+ array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef WORD val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+ // lists
+ //
+
+ template< >
+ struct customization< ::CObList > :
+ list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef list_iterator<X, ::CObject *> mutable_iterator;
+ #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ typedef list_iterator<X const, ::CObject const *> const_iterator;
+ #else
+ typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
+ #endif
+ };
+ };
+
+
+ template< >
+ struct customization< ::CPtrList > :
+ list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef list_iterator<X, void *> mutable_iterator;
+ #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ typedef list_iterator<X const, void const *> const_iterator;
+ #else
+ typedef list_iterator<X const, void const * const, void const * const> const_iterator;
+ #endif
+ };
+ };
+
+
+ template< >
+ struct customization< ::CStringList > :
+ list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef ::CString val_t;
+
+ typedef list_iterator<X, val_t> mutable_iterator;
+ #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ typedef list_iterator<X const, val_t const> const_iterator;
+ #else
+ typedef list_iterator<X const, val_t const, val_t const> const_iterator;
+ #endif
+ };
+ };
+
+
+ // mfc_map_iterator
+ //
+
+ template< class MapT, class KeyT, class MappedT >
+ struct mfc_map_iterator;
+
+ template< class MapT, class KeyT, class MappedT >
+ struct mfc_map_iterator_super
+ {
+ typedef iterator_facade<
+ mfc_map_iterator<MapT, KeyT, MappedT>,
+ std::pair<KeyT, MappedT>,
+ forward_traversal_tag,
+ std::pair<KeyT, MappedT> const
+ > type;
+ };
+
+ template< class MapT, class KeyT, class MappedT >
+ struct mfc_map_iterator :
+ mfc_map_iterator_super<MapT, KeyT, MappedT>::type
+ {
+ private:
+ typedef mfc_map_iterator self_t;
+ typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
+ typedef typename super_t::reference ref_t;
+
+ public:
+ explicit mfc_map_iterator()
+ { }
+
+ explicit mfc_map_iterator(MapT const& map, POSITION pos) :
+ m_pmap(boost::addressof(map)), m_posNext(pos)
+ {
+ increment();
+ }
+
+ explicit mfc_map_iterator(MapT const& map) :
+ m_pmap(&map), m_pos(0) // end iterator
+ { }
+
+ template< class, class, class > friend struct mfc_map_iterator;
+ template< class MapT_, class KeyT_, class MappedT_>
+ mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
+ m_pmap(other.m_pmap),
+ m_pos(other.m_pos), m_posNext(other.m_posNext),
+ m_key(other.m_key), m_mapped(other.m_mapped)
+ { }
+
+ private:
+ MapT const *m_pmap;
+ POSITION m_pos, m_posNext;
+ KeyT m_key; MappedT m_mapped;
+
+ friend class iterator_core_access;
+ ref_t dereference() const
+ {
+ BOOST_ASSERT(m_pos != 0 && "out of range");
+ return std::make_pair(m_key, m_mapped);
+ }
+
+ void increment()
+ {
+ BOOST_ASSERT(m_pos != 0 && "out of range");
+
+ if (m_posNext == 0) {
+ m_pos = 0;
+ return;
+ }
+
+ m_pos = m_posNext;
+ m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
+ }
+
+ bool equal(self_t const& other) const
+ {
+ BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
+ return m_pos == other.m_pos;
+ }
+ };
+
+ struct mfc_map_functions
+ {
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ return Iterator(x, x.GetStartPosition());
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return Iterator(x);
+ }
+ };
+
+
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+
+
+ // mfc_cpair_map_iterator
+ //
+ // used by ::CMap and ::CMapStringToString
+ //
+
+ template< class MapT, class PairT >
+ struct mfc_cpair_map_iterator;
+
+ template< class MapT, class PairT >
+ struct mfc_pget_map_iterator_super
+ {
+ typedef iterator_facade<
+ mfc_cpair_map_iterator<MapT, PairT>,
+ PairT,
+ forward_traversal_tag
+ > type;
+ };
+
+ template< class MapT, class PairT >
+ struct mfc_cpair_map_iterator :
+ mfc_pget_map_iterator_super<MapT, PairT>::type
+ {
+ private:
+ typedef mfc_cpair_map_iterator self_t;
+ typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
+ typedef typename super_t::reference ref_t;
+
+ public:
+ explicit mfc_cpair_map_iterator()
+ { }
+
+ explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
+ m_pmap(boost::addressof(map)), m_pp(pp)
+ { }
+
+ template< class, class > friend struct mfc_cpair_map_iterator;
+ template< class MapT_, class PairT_>
+ mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
+ m_pmap(other.m_pmap), m_pp(other.m_pp)
+ { }
+
+ private:
+ MapT *m_pmap;
+ PairT *m_pp;
+
+ friend class iterator_core_access;
+ ref_t dereference() const
+ {
+ BOOST_ASSERT(m_pp != 0 && "out of range");
+ return *m_pp;
+ }
+
+ void increment()
+ {
+ BOOST_ASSERT(m_pp != 0 && "out of range");
+ m_pp = m_pmap->PGetNextAssoc(m_pp);
+ }
+
+ bool equal(self_t const& other) const
+ {
+ BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
+ return m_pp == other.m_pp;
+ }
+ };
+
+ struct mfc_cpair_map_functions
+ {
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ // Workaround:
+ // Assertion fails if empty.
+ // MFC document is wrong.
+ #if !defined(NDEBUG)
+ if (x.GetCount() == 0)
+ return Iterator(x, 0);
+ #endif
+
+ return Iterator(x, x.PGetFirstAssoc());
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return Iterator(x, 0);
+ }
+ };
+
+
+#endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
+
+
+ // maps
+ //
+
+ template< >
+ struct customization< ::CMapPtrToWord > :
+ mfc_map_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef void *key_t;
+ typedef WORD mapped_t;
+
+ typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CMapPtrToPtr > :
+ mfc_map_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef void *key_t;
+ typedef void *mapped_t;
+
+ typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CMapStringToOb > :
+ mfc_map_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef ::CString key_t;
+ typedef ::CObject *mapped_t;
+
+ typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CMapStringToPtr > :
+ mfc_map_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef ::CString key_t;
+ typedef void *mapped_t;
+
+ typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CMapStringToString > :
+ #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+ mfc_cpair_map_functions
+ #else
+ mfc_map_functions
+ #endif
+ {
+ template< class X >
+ struct meta
+ {
+ #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+ typedef typename X::CPair pair_t;
+
+ typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
+ typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
+ #else
+ typedef ::CString key_t;
+ typedef ::CString mapped_t;
+
+ typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ #endif
+ };
+ };
+
+
+ template< >
+ struct customization< ::CMapWordToOb > :
+ mfc_map_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef WORD key_t;
+ typedef ::CObject *mapped_t;
+
+ typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ };
+ };
+
+
+ template< >
+ struct customization< ::CMapWordToPtr > :
+ mfc_map_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef WORD key_t;
+ typedef void *mapped_t;
+
+ typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ };
+ };
+
+
+ // templates
+ //
+
+ template< class Type, class ArgType >
+ struct customization< ::CArray<Type, ArgType> > :
+ array_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef Type val_t;
+
+ typedef val_t *mutable_iterator;
+ typedef val_t const *const_iterator;
+ };
+ };
+
+
+ template< class Type, class ArgType >
+ struct customization< ::CList<Type, ArgType> > :
+ list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef Type val_t;
+
+ typedef list_iterator<X, val_t> mutable_iterator;
+ #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ typedef list_iterator<X const, val_t const> const_iterator;
+ #else
+ typedef list_iterator<X const, val_t const, val_t const> const_iterator;
+ #endif
+ };
+ };
+
+
+ template< class Key, class ArgKey, class Mapped, class ArgMapped >
+ struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
+ #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+ mfc_cpair_map_functions
+ #else
+ mfc_map_functions
+ #endif
+ {
+ template< class X >
+ struct meta
+ {
+ #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+ typedef typename X::CPair pair_t;
+
+ typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
+ typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
+ #else
+ typedef Key key_t;
+ typedef Mapped mapped_t;
+
+ typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ #endif
+ };
+ };
+
+
+ template< class BaseClass, class PtrType >
+ struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
+ {
+ template< class X >
+ struct fun
+ {
+ typedef typename remove_pointer<PtrType>::type val_t;
+
+ typedef typename mpl::if_< is_const<X>,
+ val_t const,
+ val_t
+ >::type val_t_;
+
+ typedef val_t_ * const result_type;
+
+ template< class PtrType_ >
+ result_type operator()(PtrType_ p) const
+ {
+ return static_cast<result_type>(p);
+ }
+ };
+
+ template< class X >
+ struct meta
+ {
+ typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
+ typedef typename range_const_iterator<BaseClass>::type citer_t;
+
+ typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
+ typedef transform_iterator<fun<X const>, citer_t> const_iterator;
+ };
+
+ template< class Iterator, class X >
+ Iterator begin(X& x)
+ {
+ return Iterator(boost::begin<BaseClass>(x), fun<X>());
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return Iterator(boost::end<BaseClass>(x), fun<X>());
+ }
+ };
+
+
+ template< class BaseClass, class PtrType >
+ struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
+ list_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef typename remove_pointer<PtrType>::type val_t;
+
+ // not l-value
+ typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
+ typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
+ };
+ };
+
+
+ template< class BaseClass, class KeyPtrType, class MappedPtrType >
+ struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
+ mfc_map_functions
+ {
+ template< class X >
+ struct meta
+ {
+ typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
+ typedef mutable_iterator const_iterator;
+ };
+ };
+
+
+ // strings
+ //
+
+#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+
+ template< >
+ struct customization< ::CString >
+ {
+ template< class X >
+ struct meta
+ {
+ // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
+ typedef TCHAR *mutable_iterator;
+ typedef TCHAR const *const_iterator;
+ };
+
+ template< class Iterator, class X >
+ typename mutable_<Iterator, X>::type begin(X& x)
+ {
+ return x.GetBuffer(0);
+ }
+
+ template< class Iterator, class X >
+ Iterator begin(X const& x)
+ {
+ return x;
+ }
+
+ template< class Iterator, class X >
+ Iterator end(X& x)
+ {
+ return begin<Iterator>(x) + x.GetLength();
+ }
+ };
+
+#endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+
+
+} } // namespace boost::range_detail_microsoft
+
+
+
+
+// range customizations
+//
+
+
+// arrays
+//
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CByteArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CDWordArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CStringArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CUIntArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CWordArray
+)
+
+
+// lists
+//
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CObList
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CPtrList
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CStringList
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CObArray
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CPtrArray
+)
+
+
+// maps
+//
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CMapPtrToWord
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CMapPtrToPtr
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CMapStringToOb
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CMapStringToPtr
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CMapStringToString
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CMapWordToOb
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CMapWordToPtr
+)
+
+
+// templates
+//
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CArray, 2
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CList, 2
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CMap, 4
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CTypedPtrArray, 2
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CTypedPtrList, 2
+)
+
+BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CTypedPtrMap, 3
+)
+
+
+// strings
+//
+#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+
+ BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
+ boost::range_detail_microsoft::using_type_as_tag,
+ BOOST_PP_NIL, CString
+ )
+
+#endif
+
+
+
+
+#endif
diff --git a/src/boost/range/mutable_iterator.hpp b/src/boost/range/mutable_iterator.hpp
new file mode 100644
index 0000000..7beca66
--- /dev/null
+++ b/src/boost/range/mutable_iterator.hpp
@@ -0,0 +1,67 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_MUTABLE_ITERATOR_HPP
+#define BOOST_RANGE_MUTABLE_ITERATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#include <boost/range/detail/iterator.hpp>
+#else
+
+#include <boost/range/detail/extract_optional_type.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <cstddef>
+#include <utility>
+
+namespace boost
+{
+ //////////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////////
+
+ namespace range_detail {
+ BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( iterator )
+ }
+
+ template< typename C >
+ struct range_mutable_iterator : range_detail::extract_iterator<C>
+ {};
+
+ //////////////////////////////////////////////////////////////////////////
+ // pair
+ //////////////////////////////////////////////////////////////////////////
+
+ template< typename Iterator >
+ struct range_mutable_iterator< std::pair<Iterator,Iterator> >
+ {
+ typedef Iterator type;
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // array
+ //////////////////////////////////////////////////////////////////////////
+
+ template< typename T, std::size_t sz >
+ struct range_mutable_iterator< T[sz] >
+ {
+ typedef T* type;
+ };
+
+} // namespace boost
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#endif
diff --git a/src/boost/range/numeric.hpp b/src/boost/range/numeric.hpp
new file mode 100644
index 0000000..bfd1049
--- /dev/null
+++ b/src/boost/range/numeric.hpp
@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file algorithm.hpp
+/// Contains range-based versions of the std algorithms
+//
+/////////////////////////////////////////////////////////////////////////////
+// Copyright 2009 Neil Groves.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Copyright 2006 Thorsten Ottosen.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Copyright 2004 Eric Niebler.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+ #pragma once
+#endif
+
+#ifndef BOOST_RANGE_NUMERIC_HPP
+#define BOOST_RANGE_NUMERIC_HPP
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/distance.hpp>
+#include <numeric>
+
+
+namespace boost
+{
+ template< class SinglePassRange, class Value >
+ inline Value accumulate( const SinglePassRange& rng, Value init )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::accumulate( boost::begin(rng), boost::end(rng), init );
+ }
+
+ template< class SinglePassRange, class Value, class BinaryOperation >
+ inline Value accumulate( const SinglePassRange& rng, Value init, BinaryOperation op )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::accumulate( boost::begin(rng), boost::end(rng), init, op );
+ }
+
+
+ template< class SinglePassRange1, class SinglePassRange2, class Value >
+ inline Value inner_product( const SinglePassRange1& rng1, const SinglePassRange2& rng2, Value init )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ BOOST_ASSERT( boost::distance(rng2) >= boost::distance(rng1) );
+ return std::inner_product( boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), init );
+ }
+
+ template< class SinglePassRange1,
+ class SinglePassRange2,
+ class Value,
+ class BinaryOperation1, class BinaryOperation2 >
+ inline Value inner_product( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
+ Value init,
+ BinaryOperation1 op1, BinaryOperation2 op2 )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
+ BOOST_ASSERT( boost::distance(rng2) >= boost::distance(rng1) );
+
+ return std::inner_product( boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), init, op1, op2 );
+ }
+
+ template< class SinglePassRange, class OutputIterator >
+ inline OutputIterator partial_sum ( const SinglePassRange& rng,
+ OutputIterator result )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::partial_sum( boost::begin(rng), boost::end(rng), result );
+ }
+
+ template< class SinglePassRange, class OutputIterator, class BinaryOperation >
+ inline OutputIterator partial_sum ( const SinglePassRange& rng, OutputIterator result,
+ BinaryOperation op )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::partial_sum( boost::begin(rng), boost::end(rng), result, op );
+ }
+
+ template< class SinglePassRange, class OutputIterator >
+ inline OutputIterator adjacent_difference ( const SinglePassRange& rng,
+ OutputIterator result )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
+ return std::adjacent_difference( boost::begin(rng), boost::end(rng),
+ result );
+ }
+
+ template< class SinglePassRange, class OutputIterator, class BinaryOperation >
+ inline OutputIterator adjacent_difference ( const SinglePassRange& rng,
+ OutputIterator result,
+ BinaryOperation op )
+ {
+ BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
+ return std::adjacent_difference( boost::begin(rng), boost::end(rng),
+ result, op );
+ }
+
+}
+
+#endif
diff --git a/src/boost/range/pointer.hpp b/src/boost/range/pointer.hpp
new file mode 100644
index 0000000..e7431ff
--- /dev/null
+++ b/src/boost/range/pointer.hpp
@@ -0,0 +1,29 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2006. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_POINTER_TYPE_HPP
+#define BOOST_RANGE_POINTER_TYPE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+ template< class T >
+ struct range_pointer : iterator_pointer< typename range_iterator<T>::type >
+ { };
+}
+
+#endif
diff --git a/src/boost/range/rbegin.hpp b/src/boost/range/rbegin.hpp
new file mode 100644
index 0000000..78e5f61
--- /dev/null
+++ b/src/boost/range/rbegin.hpp
@@ -0,0 +1,65 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_RBEGIN_HPP
+#define BOOST_RANGE_RBEGIN_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/end.hpp>
+#include <boost/range/reverse_iterator.hpp>
+
+namespace boost
+{
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+rbegin( C& c )
+{
+ return BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type( boost::end( c ) );
+}
+
+#else
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+rbegin( C& c )
+{
+ typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+ iter_type;
+ return iter_type( boost::end( c ) );
+}
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
+rbegin( const C& c )
+{
+ typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
+ iter_type;
+ return iter_type( boost::end( c ) );
+}
+
+#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const T>::type
+const_rbegin( const T& r )
+{
+ return boost::rbegin( r );
+}
+
+} // namespace 'boost'
+
+#endif
+
diff --git a/src/boost/range/reference.hpp b/src/boost/range/reference.hpp
new file mode 100644
index 0000000..d308e43
--- /dev/null
+++ b/src/boost/range/reference.hpp
@@ -0,0 +1,29 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_REFERENCE_TYPE_HPP
+#define BOOST_RANGE_REFERENCE_TYPE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+ template< class T >
+ struct range_reference : iterator_reference< typename range_iterator<T>::type >
+ { };
+}
+
+#endif
diff --git a/src/boost/range/rend.hpp b/src/boost/range/rend.hpp
new file mode 100644
index 0000000..fd79aa2
--- /dev/null
+++ b/src/boost/range/rend.hpp
@@ -0,0 +1,65 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_REND_HPP
+#define BOOST_RANGE_REND_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/begin.hpp>
+#include <boost/range/reverse_iterator.hpp>
+
+namespace boost
+{
+
+#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+rend( C& c )
+{
+ return BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type( boost::begin( c ) );
+}
+
+#else
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+rend( C& c )
+{
+ typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
+ iter_type;
+ return iter_type( boost::begin( c ) );
+}
+
+template< class C >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
+rend( const C& c )
+{
+ typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<const C>::type
+ iter_type;
+ return iter_type( boost::begin( c ) );
+}
+
+#endif
+
+template< class T >
+inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<const T>::type
+const_rend( const T& r )
+{
+ return boost::rend( r );
+}
+
+} // namespace 'boost'
+
+#endif
+
diff --git a/src/boost/range/result_iterator.hpp b/src/boost/range/result_iterator.hpp
new file mode 100644
index 0000000..ba09c5f
--- /dev/null
+++ b/src/boost/range/result_iterator.hpp
@@ -0,0 +1,33 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_RESULT_ITERATOR_HPP
+#define BOOST_RANGE_RESULT_ITERATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/range/iterator.hpp>
+
+namespace boost
+{
+ //
+ // This interface is deprecated, use range_iterator<T>
+ //
+
+ template< typename C >
+ struct range_result_iterator : range_iterator<C>
+ { };
+
+} // namespace boost
+
+
+#endif
diff --git a/src/boost/range/reverse_iterator.hpp b/src/boost/range/reverse_iterator.hpp
new file mode 100644
index 0000000..f8e9221
--- /dev/null
+++ b/src/boost/range/reverse_iterator.hpp
@@ -0,0 +1,40 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_REVERSE_ITERATOR_HPP
+#define BOOST_RANGE_REVERSE_ITERATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+
+
+namespace boost
+{
+ //////////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////////
+
+ template< typename C >
+ struct range_reverse_iterator
+ {
+ typedef reverse_iterator<
+ BOOST_DEDUCED_TYPENAME range_iterator<C>::type > type;
+ };
+
+
+} // namespace boost
+
+
+#endif
diff --git a/src/boost/range/reverse_result_iterator.hpp b/src/boost/range/reverse_result_iterator.hpp
new file mode 100644
index 0000000..62bf135
--- /dev/null
+++ b/src/boost/range/reverse_result_iterator.hpp
@@ -0,0 +1,32 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_REVERSE_RESULT_ITERATOR_HPP
+#define BOOST_RANGE_REVERSE_RESULT_ITERATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/range/reverse_iterator.hpp>
+
+namespace boost
+{
+ //
+ // This interface is deprecated, use range_reverse_iterator<T>
+ //
+
+ template< typename C >
+ struct range_reverse_result_iterator : range_reverse_iterator<C>
+ { };
+
+} // namespace boost
+
+#endif
diff --git a/src/boost/range/size.hpp b/src/boost/range/size.hpp
new file mode 100644
index 0000000..6ae74d1
--- /dev/null
+++ b/src/boost/range/size.hpp
@@ -0,0 +1,52 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_SIZE_HPP
+#define BOOST_RANGE_SIZE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/assert.hpp>
+
+namespace boost
+{
+ namespace range_detail
+ {
+ template<class SinglePassRange>
+ inline BOOST_DEDUCED_TYPENAME range_size<const SinglePassRange>::type
+ range_calculate_size(const SinglePassRange& rng)
+ {
+ BOOST_ASSERT( (boost::end(rng) - boost::begin(rng)) >= 0 &&
+ "reachability invariant broken!" );
+ return boost::end(rng) - boost::begin(rng);
+ }
+ }
+
+ template<class SinglePassRange>
+ inline BOOST_DEDUCED_TYPENAME range_size<const SinglePassRange>::type
+ size(const SinglePassRange& rng)
+ {
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3) \
+ /**/
+ using namespace range_detail;
+#endif
+ return range_calculate_size(rng);
+ }
+
+} // namespace 'boost'
+
+#endif
diff --git a/src/boost/range/size_type.hpp b/src/boost/range/size_type.hpp
new file mode 100644
index 0000000..c6fb54b
--- /dev/null
+++ b/src/boost/range/size_type.hpp
@@ -0,0 +1,89 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_SIZE_TYPE_HPP
+#define BOOST_RANGE_SIZE_TYPE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/difference_type.hpp>
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#include <boost/range/detail/size_type.hpp>
+#else
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <cstddef>
+#include <utility>
+
+namespace boost
+{
+ namespace detail
+ {
+
+ //////////////////////////////////////////////////////////////////////////
+ // default
+ //////////////////////////////////////////////////////////////////////////
+
+ template<typename T>
+ class has_size_type
+ {
+ typedef char no_type;
+ struct yes_type { char dummy[2]; };
+
+ template<typename C>
+ static yes_type test(BOOST_DEDUCED_TYPENAME C::size_type x);
+
+ template<typename C, typename Arg>
+ static no_type test(Arg x);
+
+ public:
+ static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+ };
+
+ template<typename C, typename Enabler=void>
+ struct range_size
+ {
+ typedef BOOST_DEDUCED_TYPENAME make_unsigned<
+ BOOST_DEDUCED_TYPENAME range_difference<C>::type
+ >::type type;
+ };
+
+ template<typename C>
+ struct range_size<
+ C,
+ BOOST_DEDUCED_TYPENAME enable_if<has_size_type<C>, void>::type
+ >
+ {
+ typedef BOOST_DEDUCED_TYPENAME C::size_type type;
+ };
+
+ }
+
+ template< class T >
+ struct range_size :
+ detail::range_size<T>
+ { };
+
+ template< class T >
+ struct range_size<const T >
+ : detail::range_size<T>
+ { };
+
+} // namespace boost
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+
+#endif
diff --git a/src/boost/range/sub_range.hpp b/src/boost/range/sub_range.hpp
new file mode 100644
index 0000000..0b00086
--- /dev/null
+++ b/src/boost/range/sub_range.hpp
@@ -0,0 +1,182 @@
+// Boost.Range library
+//
+// Copyright Neil Groves 2009.
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_SUB_RANGE_HPP
+#define BOOST_RANGE_SUB_RANGE_HPP
+
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ #pragma warning( push )
+ #pragma warning( disable : 4996 )
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/range/size_type.hpp>
+#include <boost/range/difference_type.hpp>
+#include <boost/range/algorithm/equal.hpp>
+#include <boost/assert.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost
+{
+
+ template< class ForwardRange >
+ class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
+ {
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator_t;
+ typedef iterator_range< iterator_t > base;
+
+ typedef BOOST_DEDUCED_TYPENAME base::impl impl;
+ public:
+ typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type iterator;
+ typedef BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type const_iterator;
+ typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
+ typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
+ typedef BOOST_DEDUCED_TYPENAME base::reference reference;
+
+ public: // for return value of front/back
+ typedef BOOST_DEDUCED_TYPENAME
+ boost::mpl::if_< boost::is_reference<reference>,
+ const BOOST_DEDUCED_TYPENAME boost::remove_reference<reference>::type&,
+ reference >::type const_reference;
+
+ public:
+ sub_range() : base()
+ { }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
+ sub_range( const sub_range& r )
+ : base( static_cast<const base&>( r ) )
+ { }
+#endif
+
+ template< class ForwardRange2 >
+ sub_range( ForwardRange2& r ) :
+
+#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
+ base( impl::adl_begin( r ), impl::adl_end( r ) )
+#else
+ base( r )
+#endif
+ { }
+
+ template< class ForwardRange2 >
+ sub_range( const ForwardRange2& r ) :
+
+#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
+ base( impl::adl_begin( r ), impl::adl_end( r ) )
+#else
+ base( r )
+#endif
+ { }
+
+ template< class Iter >
+ sub_range( Iter first, Iter last ) :
+ base( first, last )
+ { }
+
+ template< class ForwardRange2 >
+ sub_range& operator=( ForwardRange2& r )
+ {
+ base::operator=( r );
+ return *this;
+ }
+
+ template< class ForwardRange2 >
+ sub_range& operator=( const ForwardRange2& r )
+ {
+ base::operator=( r );
+ return *this;
+ }
+
+ sub_range& operator=( const sub_range& r )
+ {
+ base::operator=( static_cast<const base&>(r) );
+ return *this;
+ }
+
+ public:
+
+ iterator begin() { return base::begin(); }
+ const_iterator begin() const { return base::begin(); }
+ iterator end() { return base::end(); }
+ const_iterator end() const { return base::end(); }
+ difference_type size() const { return base::size(); }
+
+
+ public: // convenience
+ reference front()
+ {
+ return base::front();
+ }
+
+ const_reference front() const
+ {
+ return base::front();
+ }
+
+ reference back()
+ {
+ return base::back();
+ }
+
+ const_reference back() const
+ {
+ return base::back();
+ }
+
+ reference operator[]( difference_type sz )
+ {
+ return base::operator[](sz);
+ }
+
+ const_reference operator[]( difference_type sz ) const
+ {
+ return base::operator[](sz);
+ }
+
+ };
+
+ template< class ForwardRange, class ForwardRange2 >
+ inline bool operator==( const sub_range<ForwardRange>& l,
+ const sub_range<ForwardRange2>& r )
+ {
+ return boost::equal( l, r );
+ }
+
+ template< class ForwardRange, class ForwardRange2 >
+ inline bool operator!=( const sub_range<ForwardRange>& l,
+ const sub_range<ForwardRange2>& r )
+ {
+ return !boost::equal( l, r );
+ }
+
+ template< class ForwardRange, class ForwardRange2 >
+ inline bool operator<( const sub_range<ForwardRange>& l,
+ const sub_range<ForwardRange2>& r )
+ {
+ return iterator_range_detail::less_than( l, r );
+ }
+
+
+} // namespace 'boost'
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ #pragma warning( pop )
+#endif
+
+#endif
+
diff --git a/src/boost/range/value_type.hpp b/src/boost/range/value_type.hpp
new file mode 100644
index 0000000..95c7580
--- /dev/null
+++ b/src/boost/range/value_type.hpp
@@ -0,0 +1,34 @@
+// Boost.Range library
+//
+// Copyright Thorsten Ottosen 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org/libs/range/
+//
+
+#ifndef BOOST_RANGE_VALUE_TYPE_HPP
+#define BOOST_RANGE_VALUE_TYPE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/range/config.hpp>
+#include <boost/range/iterator.hpp>
+
+//#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+//#include <boost/range/detail/value_type.hpp>
+//#else
+
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost
+{
+ template< class T >
+ struct range_value : iterator_value< typename range_iterator<T>::type >
+ { };
+}
+
+#endif
diff --git a/src/common/ColourTableDefinitionCompute.cc b/src/common/ColourTableDefinitionCompute.cc
index 6e9cc32..76cb16c 100644
--- a/src/common/ColourTableDefinitionCompute.cc
+++ b/src/common/ColourTableDefinitionCompute.cc
@@ -115,12 +115,12 @@ if ( minColour_.white() ) {
hmin.hue_ = hmax.hue_;
}
- //cout << maxColour_ << "WHITE???" << endl;
+
if ( maxColour_.white() ) {
step_sat = 0;
step_hue = 0;
- //cout << maxColour_ << "WHITE" << endl;
+
}
diff --git a/src/common/GeoRectangularProjection.cc b/src/common/GeoRectangularProjection.cc
index 24e7bef..26e80ed 100644
--- a/src/common/GeoRectangularProjection.cc
+++ b/src/common/GeoRectangularProjection.cc
@@ -71,12 +71,10 @@ PaperPoint GeoRectangularProjection::operator()(const UserPoint& point) const
return PaperPoint(point.x(), point.y(), point.value(), point.missing(), point.border(), 0, point.name());
}
- if ( point.y() < -85.)
- cout << point.y() << endl;
+
TeCoord2D geo = TeCoord2D(point.x()*TeCDR, point.y()*TeCDR);
TeCoord2D xy = projection_->LL2PC(geo);
- if ( point.y() < -85.)
- cout << xy.y() << endl;
+
return PaperPoint(xy.x(), xy.y(), point.value(), point.missing(), point.border(), 0, point.name());
}
diff --git a/src/common/MagicsCalls.cc b/src/common/MagicsCalls.cc
index ac94fee..e818d2a 100644
--- a/src/common/MagicsCalls.cc
+++ b/src/common/MagicsCalls.cc
@@ -1317,7 +1317,6 @@ void mag_setc(const char* name, const char* value)
string n(name);
string v(value);
psetc_(n.c_str(), value, n.size(), v.size());
- //cout << "setc("<<name<<","<<value<<")"<<endl;
}
void mag_setr(const char* name, const double value)
@@ -1332,20 +1331,18 @@ void mag_setr(const char* name, const double value)
{
MagLog::error() << e << "\n";
}
- //cout << "setr("<<name<<","<<value<<")"<<endl;
}
void mag_seti(const char* name, const int value)
{
string n(name);
pseti_(name, &value, n.size());
- //cout << "seti("<<name<<","<<value<<")"<<endl;
}
void mag_setp(const char* name, void* value)
{
+ string n(name);
#ifdef HAVE_CAIRO
- string n(name);
if ( magCompare(n, "output_cairo_drawing_context") ) {
ParameterManager::set("output_cairo_drawing_context", (CairoPtr)value);
}
@@ -1468,7 +1465,6 @@ void mag_set1c(const char* name, const char** data, const int dim)
{
MagLog::error() << e << "\n";
}
- //cout << "set1c("<<name<<","<<data[0]<<","<<dim<<")"<<endl;
}
void mag_enqr(const char* fname, double *value)
diff --git a/src/common/Matrix.cc b/src/common/Matrix.cc
index 9fc694a..d0bb1be 100644
--- a/src/common/Matrix.cc
+++ b/src/common/Matrix.cc
@@ -469,7 +469,7 @@ double Matrix::operator()(int row, int column) const
GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Transformation& transformation):
TransformMatrixHandler(matrix), transformation_(transformation), original_(0)
{
- cout << "HI" << endl;
+
map<double, int> lats;
map<double, int> lons;
@@ -479,15 +479,10 @@ GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Tra
transformation.boundingBox(minlon, minlat, maxlon, maxlat);
- cout << minlon << ", " << maxlon << endl;
-
int rows = matrix_.rows();
int columns = matrix_.columns();
double step = matrix_.XResolution();
- cout << "step --> " << step << ":" << columns << "!" << endl;
bool global = ( matrix_.regular_column(columns-1) - matrix_.regular_column(0) ) > ( 360. - 2 *matrix_.XResolution() );
- global = true;
-
if (!global) {
lon = matrix_.column(0, 0) - step;
@@ -514,15 +509,12 @@ GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Tra
for (int i = 0; i < columns; i++)
{
lon = matrix_.regular_column(i);
- cout << lon << endl;
if ( minlon <= lon && lon <= maxlon)
lons[lon] = i;
double ml = lon - 360;
while ( ml >= minlon && ml <= maxlon ) { lons[ml] = i; ml -= 360; }
-
ml = lon + 360;
-
while ( ml >= minlon && ml <= maxlon ) { lons[ml] = i; ml += 360; }
}
@@ -530,7 +522,6 @@ GeoBoxMatrixHandler::GeoBoxMatrixHandler(const AbstractMatrix& matrix, const Tra
int i = 0;
for (map<double, int>::const_iterator entry = lons.begin(); entry != lons.end(); ++entry)
{
- cout << entry->first<< endl;
columns_[i] = entry->second;
regular_longitudes_.push_back(entry->first);
columnsMap_[entry->first] = i;
diff --git a/src/common/MatrixHandler.h b/src/common/MatrixHandler.h
index cfa6f0a..80c588b 100644
--- a/src/common/MatrixHandler.h
+++ b/src/common/MatrixHandler.h
@@ -60,10 +60,10 @@ public :
double& column1, int& index1, double& column2, int& index2) const
{ return matrix_.boundColumn(r, column1, index1, column2, index2); }
- virtual double left() const { return matrix_.left(); }
- virtual double bottom() const { return matrix_.bottom(); }
- virtual double right() const { return matrix_.right(); }
- virtual double top() const { return matrix_.top(); }
+ double left() const { return matrix_.left(); }
+ double bottom() const { return matrix_.bottom(); }
+ double right() const { return matrix_.right(); }
+ double top() const { return matrix_.top(); }
double x(double x, double y) const { return matrix_.x(x, y); }
double y(double x, double y) const { return matrix_.y(x, y); }
@@ -495,15 +495,11 @@ public :
- double interpolate(double row, double column) const { return matrix_.interpolate(row, column); }
- double nearest(double row, double column) const { return matrix_.nearest(row, column); }
+ double interpolate(double row, double column) const { matrix_.interpolate(row, column); }
+ double nearest(double row, double column) const { matrix_.nearest(row, column); }
- double column(int i, int j) { return matrix_.column(i, j); }
- double row(int i, int j) { return matrix_.row(i, j); }
- double left() const { return matrix_.left(); }
- double bottom() const { return matrix_.bottom(); }
- double right() const { return matrix_.right(); }
- double top() const { return matrix_.top(); }
+ double column(int i, int j) const { matrix_.column(i, j); }
+ double row(int i, int j) const { matrix_.row(i, j); }
protected :
diff --git a/src/common/Proj4Projection.cc b/src/common/Proj4Projection.cc
index fcecb5d..b4132f3 100644
--- a/src/common/Proj4Projection.cc
+++ b/src/common/Proj4Projection.cc
@@ -79,17 +79,17 @@ public:
}
void geosinit(const Proj4Projection& from) {
- //cout << from.vertical_longitude_ << endl;
+
minlon_ = from.vertical_longitude_ - 80;
maxlon_ = from.vertical_longitude_ + 80;
minlat_ = -80;
maxlat_ = 80;
- //cout << minlon_ << " " << maxlon_ << endl;
+
ostringstream def;
def << "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=" << from.vertical_longitude_;
definition_ = def.str();
- //cout << definition_ << endl;
+
}
@@ -560,7 +560,6 @@ void Proj4Projection::boundingBox(double& xmin, double& ymin, double& xmax, doub
xmin = gridMinLon_-5;
ymax = gridMaxLat_;
xmax = gridMaxLon_+5;
- //cout << "Bounding box ->" << xmin << " " << xmax << endl;
}
double Proj4Projection::getMinX() const
@@ -950,11 +949,12 @@ void Proj4Projection::reprojectComponents(double& x, double& y, pair<double, dou
void myprint(double x, double y, bool next = false)
{
- cout << "[" << x << ", " << y << "]";
+
+ MagLog::dev() << "[" << x << ", " << y << "]";
if ( next )
- cout << "--->";
+ MagLog::dev() << "--->";
else
- cout << endl;
+ MagLog::dev() << endl;
}
void Proj4Projection::reprojectSpeedDirection(const PaperPoint& point, pair<double, double>& wind) const
diff --git a/src/decoders/CMakeLists.txt b/src/decoders/CMakeLists.txt
index af54e50..b4b796f 100644
--- a/src/decoders/CMakeLists.txt
+++ b/src/decoders/CMakeLists.txt
@@ -80,8 +80,8 @@ if (HAVE_NETCDF)
list( APPEND decoders_srcs
#Netcdf--->
decoders/NetcdfOrcaInterpretor.cc
-decoders/NetcdfData.cc
-decoders/NetcdfData.h
+decoders/Netcdf.cc
+decoders/Netcdf.h
decoders/NetcdfConvention.cc
decoders/NetcdfConvention.h
decoders/NetcdfDecoder.cc
diff --git a/src/decoders/GribDecoder.cc b/src/decoders/GribDecoder.cc
index 36614b9..4e8fc7a 100644
--- a/src/decoders/GribDecoder.cc
+++ b/src/decoders/GribDecoder.cc
@@ -2065,7 +2065,7 @@ public:
long hour = grib.getLong("hour");
long mn = grib.getLong("minute");
string x = grib.getString("dataDate");
- cout << x << endl;
+
MagDate part1 = MagDate(date);
MagTime part2 = MagTime(hour, mn, 0);
diff --git a/src/decoders/InputMatrix.cc b/src/decoders/InputMatrix.cc
index 1ffa690..36bd1af 100644
--- a/src/decoders/InputMatrix.cc
+++ b/src/decoders/InputMatrix.cc
@@ -55,7 +55,7 @@ void InputMatrix::print(ostream& out) const
MatrixHandler& InputMatrix::matrix()
{
Timer timer("InputMatrix", "Getting data");
- if ( simple_field_ )
+ if (simple_field_)
matrix_ = (*organization_).geoInterpret(&field_, *this);
this->matrixHandlers_.push_back(new MatrixHandler(*matrix_));
return *(this->matrixHandlers_.back());
@@ -84,7 +84,7 @@ void InputMatrix::getReady(const Transformation& transformation)
(*organization_).getReady(transformation);
if(transformation.coordinateType() == Transformation::GeoType ) {
- if ( !field_.empty())
+ if ( !field_.empty())
matrix_ = (*organization_).geoInterpret(&field_, *this);
if ( !u_component_.empty())
u_ = (*organization_).geoInterpret(&u_component_, *this);
diff --git a/src/decoders/InputMatrixInterpretor.cc b/src/decoders/InputMatrixInterpretor.cc
index 8d257c7..839d95e 100644
--- a/src/decoders/InputMatrixInterpretor.cc
+++ b/src/decoders/InputMatrixInterpretor.cc
@@ -73,9 +73,6 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
{
std::map<string, Mapper>::iterator mapper = mappers_.find(lowerCase(info.mapping_));
-
-
-
if ( mapper == mappers_.end() )
MagLog::warning() << "unknow input matrix mapping " << info.mapping_ << endl;
else
@@ -103,18 +100,15 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
lon = longitude_ +( i * longitude_step_);
in->columnsAxis().push_back(lon);
-
}
int nblat = in->rows();
double lat = latitude_;
- cout << nblat << endl;
+
for (int i = 0; i < nblat; i++) {
lat = latitude_ + (i*latitude_step_);
in->rowsAxis().push_back(lat);
-
}
-
in->setMapsAxis();
in->missing(std::numeric_limits<double>::max());
return in;
@@ -122,7 +116,6 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
Matrix* InputMatrixRegularInterpretor::xyInterpret(Matrix* in, const InputMatrix& info)
{
- in->akimaEnabled();
in->missing(std::numeric_limits<double>::max());
if ( !in->rowsAxis().empty() )
// WE have already initialised the matrix ..
diff --git a/src/decoders/Netcdf.cc b/src/decoders/Netcdf.cc
new file mode 100644
index 0000000..a1fcdba
--- /dev/null
+++ b/src/decoders/Netcdf.cc
@@ -0,0 +1,321 @@
+/*
+ * (C) Copyright 1996-2016 ECMWF.
+ *
+ * This software is licensed under the terms of the Apache Licence Version 2.0
+ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+ * In applying this licence, ECMWF does not waive the privileges and immunities
+ * granted to it by virtue of its status as an intergovernmental organisation nor
+ * does it submit to any jurisdiction.
+ */
+
+//! \file Netcdf.cc
+/*!
+ Sylvie Lamy-Thepaut - ECMWF Apr 02
+
+ Changes:
+
+ Apr 06: update for GCC 4.0 (Stephan)
+*/
+#include <algorithm>
+#include <Netcdf.h>
+#include <MagException.h>
+#include <MagLog.h>
+
+
+using namespace magics;
+
+
+static bool isVariable(NcVar* var)
+{
+ if (var->num_dims() != 1) return true;
+
+ string name0(var->name());
+ string name1(var->get_dim(0)->name());
+ if ( name0 == name1) return false;
+ return true;
+}
+
+template <class From, class To>
+Convertor<From,To>::Convertor(NetVariable& var) : variable_(var)
+{
+ To scale(1);
+ To offset(0);
+ scale_factor_ = variable_.getAttribute("scale_factor", scale);
+ add_offset_ = variable_.getAttribute("add_offset", offset);
+ missing_ = variable_.getMissing();
+}
+
+
+
+template <class F, class T>
+void TypedAccessor<F,T>::operator() (vector<T>& to, vector<long>& start, vector<long>& edges, NetVariable& var) const
+{
+ F* from = new F[to.size()];
+ var.id_->set_cur(&start[0]);
+ var.id_->get(from, &edges[0]);
+ // Convert the data....
+ std::transform(from, from + to.size(), to.begin(), Convertor<F, T>(var));
+ delete[] from;
+}
+
+template <class F, class T>
+void TypedAccessor<F,T>::get (vector<F>& from, vector<long>& start, vector<long>& edges, NetVariable& var)const
+{
+ var.id_->set_cur(&start[0]);
+ var.id_->get(from, &edges[0]);
+}
+
+Netcdf::Netcdf(const string& path, const string& method) : file_(path.c_str())
+{
+ if (file_.is_valid() == false) {
+ throw NoSuchNetcdfFile(path);
+ }
+ for ( int v = 0; v < file_.num_vars(); v++)
+ {
+ NcVar* var = file_.get_var(v);
+ variables_.insert(std::make_pair(var->name(), NetVariable(var->name(), var, file_, method)));
+
+ if (isVariable(var)) dataset_.insert(std::make_pair(var->name(), NetVariable(var->name(), var, file_, method)));
+ }
+ MagLog::debug() << "Initialisation of Netcdf [" << path << "] OK! " << "\n";
+ for ( int v = 0; v < file_.num_atts(); v++)
+ {
+ NcAtt* attr = file_.get_att(v);
+ attributes_.insert(std::make_pair(attr->name(), NetAttribute(attr->name(), attr)));
+ }
+ for ( int d = 0; d < file_.num_dims(); d++)
+ {
+ NcDim* var = file_.get_dim(d);
+ dimensions_.insert(std::make_pair(var->name(), NetDimension(var)));
+ }
+}
+
+
+Netcdf::~Netcdf()
+{
+}
+double Netcdf::getMissing(const string& var, const string& attr)
+{
+
+ missing_ = getAttribute(attr, getDefaultMissing(var));
+ missing_ = getVariableAttribute(var, attr, missing_);
+ return missing_;
+}
+
+void Netcdf::print(ostream& out) const
+{
+ out << "print Netcdf: " << "\n";
+ out << "Variables: " << "\n";
+ for (map<string, NetVariable>::const_iterator var = variables_.begin(); var != variables_.end(); ++var)
+ {
+ out << (*var).second;
+ }
+ out << "Dataset: " << "\n";
+ for (map<string, NetVariable>::const_iterator var = dataset_.begin(); var != dataset_.end(); ++var)
+ {
+ out << (*var).second;
+ }
+}
+
+
+struct Index
+{
+ static map<NcType, Index*>* tools_;
+ Index(NcType type)
+ {
+ if ( tools_ == 0) tools_ = new map<NcType, Index*>();
+ tools_->insert(std::make_pair(type, this));
+ }
+ virtual int operator()(const string& val, NcValues* values, long nb )
+ {
+ ASSERT(false);
+ }
+ static int get(const NcType& type, const string& val, NcValues* values, long nb)
+ {
+ map<NcType, Index*>::const_iterator tool = tools_->find(type);
+ if ( tool == tools_->end() ) {
+ ASSERT(false);
+ throw new MagicsException("No Index available");
+ }
+
+ return (*(*tool).second)(val, values, nb);
+ }
+};
+
+struct FloatIndex: public Index
+{
+ FloatIndex() : Index(ncFloat) {}
+
+ virtual int operator()(const string& val, NcValues* values, long nb )
+ {
+ float value = atof(val.c_str());
+ if ( nb == 1 && values->as_float(0) == value) return 0;
+ for (int i = 0; i < nb - 1; i++) {
+ if (values->as_float(i) == value) return i;
+ if (values->as_float(i+1) == value) return i+1;
+ if (values->as_float(i) < value && value < values->as_float(i+1) ) return i;
+ if (values->as_float(i+1) < value && value < values->as_float(i) ) return i+1;
+ }
+ throw MagicsException("No such value : " + val);
+ }
+};
+
+struct DoubleIndex: public Index
+{
+ DoubleIndex() : Index(ncDouble) {}
+
+ virtual int operator()(const string& val, NcValues* values, long nb )
+ {
+ double value = tonumber(val);
+ if ( nb == 1 && values->as_double(0) == value) return 0;
+ for (int i = 0; i < nb - 1; i++) {
+ if (values->as_double(i) == value) return i;
+ if (values->as_double(i+1) == value) return i+1;
+ if (values->as_double(i) < value && value < values->as_double(i+1) ) return i;
+ if (values->as_double(i+1) < value && value < values->as_double(i) ) return i+1;
+ }
+ throw MagicsException("No such value : " + val);
+ }
+};
+
+
+struct IntIndex: public Index
+{
+ IntIndex() : Index(ncInt) {}
+
+ virtual int operator()(const string& val, NcValues* values, long nb )
+ {
+ int value = atoi(val.c_str());
+ if ( nb == 1 && values->as_int(0) == value) return 0;
+
+ for (int i = 0; i < nb - 1; i++)
+ {
+ if (values->as_int(i) == value) return i;
+ if (values->as_int(i+1) == value) return i+1;
+ if ( values->as_int(i) < value && value < values->as_int(i+1) ) return i;
+ if ( values->as_int(i+1) < value && value < values->as_int(i) ) return i+1;
+ }
+ throw MagicsException("No such value : " + val);
+ }
+};
+
+struct StringIndex: public Index
+{
+ StringIndex() : Index(ncChar) {}
+
+ virtual int operator()(const string& val, NcValues* values, long nb )
+ {
+
+ for (int i = 0; i < nb; i++)
+ {
+ string read(values->as_string(i));
+
+ if ( read == val) {
+
+ return i/64;
+ }
+ }
+ throw MagicsException("No such value : " + val);
+ }
+};
+
+map<NcType, Index*>* Index::tools_ = 0;
+
+static FloatIndex float_index;
+static IntIndex int_index;
+static DoubleIndex double_index;
+static StringIndex string_index;
+
+int NetDimension::index(const string& val)
+{
+ int index = atoi(val.c_str());
+ // if (index < )
+ return index;
+}
+
+int NetDimension::value(const string& val)
+{
+ if ( variable_ ) {
+ int index = Index::get(variable_->type(), val, variable_->values(), variable_->num_vals());
+
+ return index;
+ }
+ // we assume the user is using a simple ..
+ int index = atoi(val.c_str());
+ MagLog::warning() << " Could not find variable return index instead " << index << endl;
+ //if (index < )
+ return index;
+}
+
+void NetDimension::first(const string& val)
+{
+
+ first_ = ( magCompare(method_, "value") ) ? value(val) : index(val);
+
+}
+
+
+void NetDimension::last(const string& val)
+{
+
+ int last = (magCompare(method_, "value")) ? value(val) : index(val);
+ if ( last < first_ )
+ {
+ MagLog::warning() << "last position (" + val + ") < first position: exchange " << "\n";
+ int tmp = first_;
+ first_ = last;
+ last = tmp;
+ }
+ dim_ = last - first_ + 1;
+}
+
+
+NetVariable::NetVariable(const string& name, NcVar* id, const NcFile& file, const string& method): name_(name), id_(id)
+ {
+ for (int d = 0; d < id_->num_dims(); d++)
+ {
+ NcDim* dim = id_->get_dim(d);
+ NcVar* var = 0;
+ string dim_name = dim->name();
+ for (int v = 0; v < file.num_vars(); v++) {
+ string var_name = file.get_var(v)->name();
+ if (var_name == dim_name) var = file.get_var(dim->name());
+
+ }
+ dimensions_[dim->name()]= NetDimension(dim, var, d);
+ dimensions_[dim->name()].method_ = method;
+ }
+ for (int a = 0; a < id_->num_atts(); a++)
+ {
+ NcAtt* att = id_->get_att(a);
+ attributes_[att->name()] = NetAttribute(att->name(), att);
+ }
+ }
+
+double NetVariable::getDefaultMissing()
+{
+
+ if (id_->type() == ncDouble)
+ return NC_FILL_DOUBLE;
+ return NC_FILL_FLOAT;
+}
+
+
+
+namespace magics {
+ template<> map<NcType, Accessor<double>*>* Accessor<double>::accessors_ = 0;
+ template<> map<NcType, Accessor<float>*>* Accessor<float>::accessors_ = 0;
+} // end namespace
+
+
+static TypedAccessor<short, float> short_float_accessor(ncShort);
+static TypedAccessor<int, float> int_float_accessor(ncInt);
+static TypedAccessor<float, float> float_float_accessor(ncFloat);
+static TypedAccessor<double, float> double_float_accessor(ncFloat);
+
+static TypedAccessor<ncbyte, double> byte_double_accessor(ncByte);
+static TypedAccessor<short, double> short_double_accessor(ncShort);
+static TypedAccessor<int, double> int_double_accessor(ncInt);
+static TypedAccessor<float, double> float_double_accessor(ncFloat);
+static TypedAccessor<double, double> double_double_accessor(ncDouble);
+
diff --git a/src/decoders/NetcdfData.h b/src/decoders/Netcdf.h
similarity index 58%
rename from src/decoders/NetcdfData.h
rename to src/decoders/Netcdf.h
index 7ddfa54..0fc2f76 100644
--- a/src/decoders/NetcdfData.h
+++ b/src/decoders/Netcdf.h
@@ -23,7 +23,7 @@
#define Netcdf_H
#include "magics.h"
-#include "netcdf.h"
+#include "netcdfcpp.h"
#include "MagException.h"
#include "MagLog.h"
@@ -56,27 +56,24 @@ public:
struct NetDimension
{
string name_;
- size_t size_;
- size_t first_;
- size_t dim_;
- size_t index_;
+ long size_;
+ long first_;
+ long dim_;
+ long index_;
string method_;
- int id_;
- int variable_;
- int netcdf_;
+ NcDim* id_;
+ NcVar* variable_;
NetDimension() {}
- NetDimension(int netcdf, const string& name, int index = 0, int variable = -1): name_(name),
- first_(0), index_(index), variable_(variable),
- netcdf_(netcdf) {
- nc_inq_dimid(netcdf, name_.c_str(), &id_);
- nc_inq_dimlen(netcdf, id_, &size_);
- dim_ = size_;
-
- }
-
-
+ NetDimension(NcDim* id): name_(id->name()), size_(id->size()),
+ first_(0), dim_(size_), index_(0),
+ id_(id), variable_(0) {}
+ NetDimension(NcDim* id, NcVar* variable, long index) :
+ name_(id->name()), size_(id->size()),
+ first_(0), dim_(size_), index_(index),
+ id_(id), variable_(variable)
+ {}
void first(const string&);
void last(const string&);
@@ -96,52 +93,23 @@ struct NetDimension
struct NetAttribute
{
string name_;
- int id_;
- int netcdf_;
- NetAttribute(const string name, int netcdf, int id) : name_(name), netcdf_(netcdf), id_(id) {}
+ NcAtt* id_;
+ NetAttribute(const string name, NcAtt* id) : name_(name), id_(id) {}
NetAttribute() {}
- void get(double& val) {
- double tmp;
- nc_get_att_double(netcdf_, id_, name_.c_str(), &tmp);
- val = tmp;
- }
- void get(float& val) {
- float tmp;
- nc_get_att_float(netcdf_, id_, name_.c_str(),
- &tmp);
- }
- void get(string& val) {
- size_t len;
- nc_inq_attlen (netcdf_, id_, name_.c_str(),&len);
- cout << "LEN" << len << endl;
- char tmp[len];
- nc_get_att_text(netcdf_, id_, name_.c_str(), tmp);
-
- val = string(tmp, len);
- cout << "get string" << val << endl;
- }
- void get(char*& val) {
- size_t len;
- nc_inq_attlen (netcdf_, id_, name_.c_str(),&len);
- char* tmp = new char[len];
- //val = new char[len];
- nc_get_att_text(netcdf_, id_, name_.c_str(), (char*)val);
-
- cout << "val get" << *val << endl;
-
- }
+ void get(double& val) { val = id_->as_double(0); }
+ void get(float& val) { val = id_->as_float(0); }
+ void get(const char*& val) { val = id_->as_string(0); }
};
class NetVariable;
-class Netcdf;
template <class From, class To>
struct Convertor
{
Convertor(NetVariable& );
To operator()(From from)
- {
+ {
return ( from != missing_) ? from * scale_factor_ + add_offset_ : missing_;
}
@@ -156,39 +124,37 @@ template <class T>
class Accessor
{
public:
- Accessor(nc_type type) {
- if ( !accessors_)
- accessors_ = new map<nc_type, Accessor<T>*>;
+ Accessor(NcType type) {
+ if ( !accessors_) accessors_ = new map<NcType, Accessor<T>*>;
accessors_->insert(std::make_pair(type, this));
}
virtual ~Accessor() { }
- virtual void operator() (vector<T>&, vector<size_t>& , vector<size_t>&, NetVariable&) const {}
+ virtual void operator() (vector<T>&, vector<long>& , vector<long>&, NetVariable&) const {}
- static map<nc_type, Accessor<T>*>* accessors_;
+ static map<NcType, Accessor<T>*>* accessors_;
static void release() {
if ( accessors_ )
- for ( typename map<nc_type, Accessor<T>*>::iterator a = accessors_->begin(); a != accessors_->end(); ++a) {
+ for ( typename map<NcType, Accessor<T>*>::iterator a = accessors_->begin(); a != accessors_->end(); ++a) {
Accessor<T>* accessor = a->second;
a->second = 0;
delete accessor;
}
}
- static void access(vector<T>& data, vector<size_t>& start, vector<size_t>& edges, NetVariable& var);
-
-
+
+ static void access(vector<T>& data, vector<long> start, vector<long> edges, NetVariable& var);
+ static void access(vector<T>& data, NetDimension& dim){}
};
template <class F, class T>
class TypedAccessor : public Accessor<T>
{
public:
- TypedAccessor(nc_type type) : Accessor<T>(type) {}
+ TypedAccessor(NcType type) : Accessor<T>(type) {}
- void operator() (vector<T>& to, vector<size_t>& start, vector<size_t>& edges, NetVariable& var) const;
- void get (vector<F>& from, vector<size_t>& start, vector<size_t>& edges, NetVariable& var) const;
-
+ void operator() (vector<T>& to, vector<long>& start, vector<long>& edges, NetVariable& var) const;
+ void get (vector<F>& from, vector<long>& start, vector<long>& edges, NetVariable& var) const;
};
@@ -196,15 +162,14 @@ public:
struct NetVariable
{
string name_;
- int id_;
- int netcdf_;
+ NcVar* id_;
map<string, NetDimension> dimensions_;
map<string, NetAttribute> attributes_;
double missing_;
- NetVariable(const string& name, int id, int netcdf, const string& method);
+ NetVariable(const string& name, NcVar* id, const NcFile& file, const string& method);
- void getStartingPoint(vector<size_t>& dims)
+ void getStartingPoint(vector<long>& dims)
{
dims.resize(dimensions_.size());
for (map<string, NetDimension>::iterator dim = dimensions_.begin(); dim != dimensions_.end(); ++dim)
@@ -213,7 +178,7 @@ struct NetVariable
}
}
- void getDimensions(vector<size_t>& dims)
+ void getDimensions(vector<long>& dims)
{
dims.resize(dimensions_.size());
for (map<string, NetDimension>::iterator dim = dimensions_.begin(); dim != dimensions_.end(); ++dim)
@@ -222,13 +187,6 @@ struct NetVariable
}
}
- size_t getSize()
- {
- vector<size_t> dims;
- getDimensions(dims);
- return getSize(dims);
-
- }
void setFirstPoint(const string& name, const string& first)
{
@@ -244,61 +202,13 @@ struct NetVariable
(*d).second.last(last);
}
- size_t getSize(const vector<size_t>& dims)
+ long getSize(const vector<long>& dims)
{
- size_t size = 1;
- for (unsigned int i = 0; i < dims.size(); i++) {
+ long size = 1;
+ for (unsigned int i = 0; i < dims.size(); i++)
size = (dims[i] ) * size;
- cout << size << endl;
- }
-
return size;
}
-
- void get(vector<double>& data, vector<size_t>& start, vector<size_t>& edges )
- {
- nc_get_vara_double(netcdf_, id_, &start.front(), &edges.front(), &data.front());
- }
-
- void get(vector<float>& data, vector<size_t>& start, vector<size_t>& edges )
- {
-
- nc_get_vara_float(netcdf_, id_, &start.front(), &edges.front(), &data.front());
- }
-
- void get(vector<int>& data, vector<size_t>& start, vector<size_t>& edges )
- {
-
- nc_get_vara_int(netcdf_, id_, &start.front(), &edges.front(), &data.front());
- }
- void get(vector<short>& data, vector<size_t>& start, vector<size_t>& edges )
- {
-
- nc_get_vara_short(netcdf_, id_, &start.front(), &edges.front(), &data.front());
- }
- void get(vector<double>& data )
- {
- nc_get_var_double(netcdf_, id_, &data.front());
- }
-
- void get(vector<float>& data)
- {
-
- nc_get_var_float(netcdf_, id_, &data.front());
- }
-
- void get(vector<int>& data )
- {
-
- nc_get_var_int(netcdf_, id_, &data.front());
- }
- void get(vector<short>& data )
- {
-
- nc_get_var_short(netcdf_, id_, &data.front());
- }
-
-
void print(ostream& s) const
{
s << name_ << "[";
@@ -313,14 +223,6 @@ struct NetVariable
}
- nc_type type() {
- nc_type type;
- nc_inq_vartype(netcdf_, id_, &type);
- return type;
- }
-
- int find(const string& value);
-
double getMissing() { return missing_; }
template <class T>
@@ -333,20 +235,6 @@ struct NetVariable
return val;
}
- string getAttribute(const string& name, const char* def)
- {
- return getAttribute(name, string(def));
-
- }
- string getAttribute(const string& name, const string& def)
- {
-
- map<string, NetAttribute>::iterator attr = attributes_.find(name);
- if ( attr == attributes_.end() ) return def;
- string val;
- (*attr).second.get(val);
- return val;
- }
double getDefaultMissing();
double getMissing(const string&);
@@ -360,15 +248,15 @@ struct NetVariable
for (map<string, string>::const_iterator f = last.begin(); f != last.end(); ++f) {
setLastPoint((*f).first, (*f).second);
}
- getValues(vals);
+ get(vals);
}
template <class T>
- void getValues(vector<T>& vals)
+ void get(vector<T>& vals)
{
- vector<size_t> start;
+ vector<long> start;
getStartingPoint(start);
- vector<size_t> end;
+ vector<long> end;
getDimensions(end);
vals.resize(getSize(end));
@@ -440,41 +328,19 @@ public:
T getVariableAttribute(const string& name, const string& attr, T def)
{
map<string, NetVariable>::iterator var = variables_.find(name);
- if ( var == variables_.end() )
- throw NoSuchNetcdfVariable(name);
- return (*var).second.getAttribute(attr, def);
- }
-
-
- string getVariableAttribute(const string& name, const string& attr, const string& def)
- {
- map<string, NetVariable>::iterator var = variables_.find(name);
- if ( var == variables_.end() )
- throw NoSuchNetcdfVariable(name);
+ if ( var == variables_.end() ) throw NoSuchNetcdfVariable(name);
return (*var).second.getAttribute(attr, def);
- }
+ }
template <class T>
T getAttribute(const string& name, T def)
{
T val;
map<string, NetAttribute>::iterator attr = attributes_.find(name);
if ( attr == attributes_.end() ) return def;
- (*attr).second.get(val);
- return val;
- }
-
- string getAttribute(const string& name, const string& def)
- {
-
- map<string, NetAttribute>::iterator attr = attributes_.find(name);
- if ( attr == attributes_.end() ) return def;
- string val;
- (*attr).second.get(val);
- cout << "VAL--->" << val << endl;
- return strdup(val.c_str());
- }
+ (*attr).second.get(val);
+ return val;
-
+ }
NetVariable getVariable(const string& name)
{
map<string, NetVariable>::iterator var = variables_.find(name);
@@ -499,28 +365,54 @@ protected:
double missing_;
private:
- int file_;
+ NcFile file_;
friend ostream& operator<<(ostream& s,const Netcdf& p)
{ p.print(s); return s; }
};
-template <class T>
-void Accessor<T>::access(vector<T>& data, vector<size_t>& start, vector<size_t>& edges, NetVariable& var)
+template <class From, class To>
+class DataAccessor
{
+public:
+ DataAccessor(Netcdf& netcdf) : netcdf_(netcdf) {}
+ void operator()(const string& name, vector<To>& to)
+ {
+ vector<From> from;
+ netcdf_.get(name, from, start_, end_);
+ int i = 0;
+ for (typename vector<From>::const_iterator val = from.begin(); val != from.end(); ++val) {
+ To add = To(*val);
+
+ to.push_back(To(*val));
+ }
+ }
+
+ void setDimension(const string& name, long from, long dim) {
+ start_.insert(std::make_pair(name, from));
+ end_.insert(std::make_pair(name, dim));
+ }
- typename map<nc_type, Accessor<T>*>::const_iterator accessor = accessors_->find(var.type());
+ void setDimension(const string& name, long val) {
+ start_.insert(std::make_pair(name, val));
+ end_.insert(std::make_pair(name, 1));
+ }
+
+ map<string, long> start_;
+ map<string, long> end_;
+ Netcdf& netcdf_;
+};
+
+template <class T>
+void Accessor<T>::access(vector<T>& data, vector<long> start, vector<long> edges, NetVariable& var)
+{
+ typename map<NcType, Accessor<T>*>::const_iterator accessor = accessors_->find(var.id_->type());
if ( accessor == accessors_->end() ) throw new MagicsException("No accessor available");
(*(*accessor).second)(data, start, edges, var);
}
-
-
-
-
-
} // Namespace Magics
diff --git a/src/decoders/NetcdfData.cc b/src/decoders/NetcdfData.cc
deleted file mode 100644
index 78e16f8..0000000
--- a/src/decoders/NetcdfData.cc
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * (C) Copyright 1996-2016 ECMWF.
- *
- * This software is licensed under the terms of the Apache Licence Version 2.0
- * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
- * In applying this licence, ECMWF does not waive the privileges and immunities
- * granted to it by virtue of its status as an intergovernmental organisation nor
- * does it submit to any jurisdiction.
- */
-
-//! \file Netcdf.cc
-/*!
- Sylvie Lamy-Thepaut - ECMWF Apr 02
-
- Changes:
-
- Apr 06: update for GCC 4.0 (Stephan)
-*/
-#include <algorithm>
-#include <NetcdfData.h>
-#include <MagException.h>
-#include <MagLog.h>
-
-
-using namespace magics;
-
-
-static bool isVariable(int netcdf, int var)
-{
- int dims;
- nc_inq_varndims(netcdf, var, &dims);
-
- if (dims != 1) return true;
-
- return false;
-}
-
-template <class From, class To>
-Convertor<From,To>::Convertor(NetVariable& var) : variable_(var)
-{
- To scale(1);
- To offset(0);
- scale_factor_ = variable_.getAttribute("scale_factor", scale);
- add_offset_ = variable_.getAttribute("add_offset", offset);
- missing_ = variable_.getMissing();
-}
-
-
-
-template <class F, class T>
-void TypedAccessor<F,T>::operator() (vector<T>& to, vector<size_t>& start, vector<size_t>& edges, NetVariable& var) const
-{
- vector<F> from(to.size());
- var.get(from, start, edges);
- // Convert the data....
- std::transform(from.begin(), from.begin() + to.size(), to.begin(), Convertor<F, T>(var));
-
-}
-
-template <class F, class T>
-void TypedAccessor<F,T>::get (vector<F>& from, vector<size_t>& start, vector<size_t>& edges, NetVariable& var)const
-{
- var.get(&from.front(), start, edges);
-}
-
-Netcdf::Netcdf(const string& path, const string& method)
-{
- int error = nc_open(path.c_str(), NC_NOWRITE, &file_);
-
- if (error) {
- throw NoSuchNetcdfFile(path);
- }
-
- int num_var;
- int var_ids[100];
- nc_inq_varids(file_, &num_var, var_ids);
-
- for ( int v = 0; v < num_var; v++)
- {
- // get the name
- string tmp;
- int id = var_ids[v];
- nc_inq_varname (file_, id, &tmp[0]);
-
- string name(tmp.c_str());
-
- variables_.insert(std::make_pair(name, NetVariable(name, v, file_, method)));
- cout << id << "--->" << name << "----> " << variables_.size() << endl;
-
- if (isVariable(file_, var_ids[v])) dataset_.insert(std::make_pair(name, NetVariable(name, var_ids[v], file_, method)));
- }
-
-
- MagLog::debug() << "Initialisation of Netcdf [" << path << "] OK! " << "\n";
-
- int num_atts;
- nc_inq_varnatts(file_, NC_GLOBAL, &num_atts);
- for ( int v = 0; v < num_atts; v++)
- {
-
- string tmp;
- nc_inq_attname(file_, NC_GLOBAL, v, &tmp[0]);
- string name(tmp.c_str());
- attributes_.insert(std::make_pair(name, NetAttribute(name, file_, NC_GLOBAL)));
- }
-
- int num_dims;
- nc_inq_ndims(file_, &num_dims);
- for ( int d = 0; d < num_dims; d++)
- {
- string tmp;
- nc_inq_dimname(file_, d, &tmp[0]);
- string name(tmp.c_str());
- dimensions_.insert(std::make_pair(name, NetDimension(file_, name)));
- }
-
- cout << *this << endl;
-
-}
-
-
-Netcdf::~Netcdf()
-{
-}
-double Netcdf::getMissing(const string& var, const string& attr)
-{
-
- missing_ = getAttribute(attr, getDefaultMissing(var));
- missing_ = getVariableAttribute(var, attr, missing_);
- return missing_;
-}
-
-void Netcdf::print(ostream& out) const
-{
- out << "print Netcdf: " << "\n";
- out << "Variables: " << "\n";
- for (map<string, NetVariable>::const_iterator var = variables_.begin(); var != variables_.end(); ++var)
- {
- out << (*var).second;
- }
- out << "Dataset: " << "\n";
- for (map<string, NetVariable>::const_iterator var = dataset_.begin(); var != dataset_.end(); ++var)
- {
- out << (*var).second;
- }
-}
-
-
-
-
-int NetDimension::index(const string& val)
-{
- int index = atoi(val.c_str());
- return index;
-}
-
-int NetDimension::value(const string& val)
-{
- if ( variable_ != -1 ) {
-
- //int index = Index::get(variable_->type(), val, variable_->values(), variable_->num_vals());
- NetVariable var(name_, variable_, netcdf_, "index");
-
- return var.find(val);
- }
-
- // we assume the user is using index! ..
- int index = atoi(val.c_str());
- MagLog::warning() << " Could not find variable return index instead " << index << endl;
- return index;
-}
-
-void NetDimension::first(const string& val)
-{
-
- first_ = ( magCompare(method_, "value") ) ? value(val) : index(val);
-
-}
-
-
-void NetDimension::last(const string& val)
-{
-
- int last = (magCompare(method_, "value")) ? value(val) : index(val);
- if ( last < first_ )
- {
- MagLog::warning() << "last position (" + val + ") < first position: exchange " << "\n";
- int tmp = first_;
- first_ = last;
- last = tmp;
- }
- dim_ = last - first_ + 1;
-}
-
-
-NetVariable::NetVariable(const string& name, int id, int file, const string& method): name_(name), id_(id), netcdf_(file)
-{
- int num_dims;
- nc_inq_varndims(netcdf_, id_, &num_dims);
- int dims[num_dims];
- nc_inq_vardimid(netcdf_, id_, dims);
-
-
- for (int d = 0; d < num_dims; d++)
- {
- string tmp;
- nc_inq_dimname(netcdf_, dims[d], &tmp[0]);
- string name(tmp.c_str());
- int var = -1;
- // Try to find if a variable is defined with this name.
- int num_var;
- int var_ids[100];
- nc_inq_varids(netcdf_, &num_var, var_ids);
-
- for ( int v = 0; v < num_var; v++)
- {
- // get the name
- string tmp;
- int id = var_ids[v];
- nc_inq_varname (netcdf_, id, &tmp[0]);
- string current(tmp.c_str());
- if ( current == name ) {
- var = id;
- cout << "Found it !" << name << endl;
- break;
- }
-
- }
- dimensions_.insert(std::make_pair(name, NetDimension(netcdf_, name, d, var)));
- dimensions_[name].method_ = method;
- }
-
-
-
- int num_atts;
- nc_inq_varnatts(netcdf_, id_, &num_atts);
- for ( int v = 0; v < num_atts; v++)
- {
-
- string tmp;
- nc_inq_attname(netcdf_, id_, v, &tmp[0]);
- string name(tmp.c_str());
- attributes_.insert(std::make_pair(name, NetAttribute(name, netcdf_, id_)));
- }
-
- missing_ = getDefaultMissing();
-}
-
-template <class T>
-int find(const T& value, vector<T>& values)
-{
- if ( values.size() == 1 && values[0] == value)
- return 0;
- for (int i = 0; i < values.size() - 1; i++) {
- if (values[i] == value) return i;
- if (values[i+1] == value) return i+1;
- if (values[i] < value && value < values[i+1] ) return i;
- if (values[i+1] < value && value < values[i] ) return i+1;
- }
- return -1;
-}
-
-int NetVariable::find(const string& val)
-{
- nc_type t = type();
- if ( t == NC_DOUBLE ) {
- vector<double> values;
- values.resize(getSize());
- get(values);
- double dval = tonumber(val);
- return ::find(dval, values);
-
- }
- if ( t == NC_INT ) {
- vector<int> values;
- values.resize(getSize());
- get(values);
- int dval = tonumber(val);
- return ::find(dval, values);
-
- }
- if ( t == NC_FLOAT ) {
- vector<float> values;
- values.resize(getSize());
- getValues(values);
- float dval = tonumber(val);
- return ::find(dval, values);
-
- }
- if ( t == NC_SHORT ) {
- vector<short> values;
- values.resize(getSize());
- get(values);
- short dval = tonumber(val);
- return ::find(dval, values);
-
- }
- return -1;
-
-}
-
-
-double NetVariable::getDefaultMissing()
-{
-
- if ( type() == NC_DOUBLE)
- return NC_FILL_DOUBLE;
- return NC_FILL_FLOAT;
-}
-
-
-
-namespace magics {
- template<> map<nc_type, Accessor<double>*>* Accessor<double>::accessors_ = 0;
- template<> map<nc_type, Accessor<float>*>* Accessor<float>::accessors_ = 0;
-} // end namespace
-
-
-static TypedAccessor<short, float> short_float_accessor(NC_SHORT);
-static TypedAccessor<int, float> int_float_accessor(NC_INT);
-static TypedAccessor<float, float> float_float_accessor(NC_FLOAT);
-static TypedAccessor<double, float> double_float_accessor(NC_FLOAT);
-
-//static TypedAccessor<nc_byte, double> byte_double_accessor(NC_BYTE);
-static TypedAccessor<short, double> short_double_accessor(NC_SHORT);
-static TypedAccessor<int, double> int_double_accessor(NC_INT);
-static TypedAccessor<float, double> float_double_accessor(NC_FLOAT);
-static TypedAccessor<double, double> double_double_accessor(NC_DOUBLE);
-
diff --git a/src/decoders/NetcdfGeoMatrixInterpretor.cc b/src/decoders/NetcdfGeoMatrixInterpretor.cc
index 3d06d2b..7b20582 100644
--- a/src/decoders/NetcdfGeoMatrixInterpretor.cc
+++ b/src/decoders/NetcdfGeoMatrixInterpretor.cc
@@ -21,7 +21,7 @@
#include "NetcdfGeoMatrixInterpretor.h"
#include "Factory.h"
-#include "NetcdfData.h"
+#include "Netcdf.h"
#include <limits>
#include "Layer.h"
@@ -42,15 +42,14 @@ bool NetcdfGeoMatrixInterpretor::interpretAsMatrix(Matrix** data)
Netcdf netcdf(path_, dimension_method_);
-
- string proj4 = netcdf.getAttribute("projection", string(""));
+ string proj4 = netcdf.getAttribute("projection", "");
if ( proj4.empty() ) {
matrix_ = new Matrix();
matrix_->akimaEnabled();
}
else {
- cout << "CREATE PROJ4 Matrix" << endl;
+
matrix_ = new Proj4Matrix(proj4);
}
*data = matrix_;
@@ -161,7 +160,7 @@ void NetcdfGeoMatrixInterpretor::visit(Transformation& transformation) {
bool NetcdfGeoMatrixInterpretor::interpretAsPoints(PointsList& list)
{
Netcdf netcdf(path_, dimension_method_);
- string proj4 = netcdf.getAttribute("projection", string(""));
+ string proj4 = netcdf.getAttribute("projection", "");
if ( !proj4.empty() ) {
proj4_ = pj_init_plus(proj4.c_str());
diff --git a/src/decoders/NetcdfGeopointsInterpretor.cc b/src/decoders/NetcdfGeopointsInterpretor.cc
index dc7518e..77a802b 100644
--- a/src/decoders/NetcdfGeopointsInterpretor.cc
+++ b/src/decoders/NetcdfGeopointsInterpretor.cc
@@ -22,7 +22,7 @@
#include "NetcdfGeopointsInterpretor.h"
#include "TextVisitor.h"
#include "Factory.h"
-#include "NetcdfData.h"
+#include "Netcdf.h"
#include <limits>
#include "Layer.h"
#include "SciMethods.h"
@@ -73,8 +73,8 @@ bool NetcdfGeopointsInterpretor::interpretAsPoints(PointsList& list, const Trans
//If the lat-lon units is specified as "radians" convert lat-lon
//to degrees. By default the units are sipposed to be "degrees"
- string units;
- if ( magCompare(netcdf.getVariableAttribute(latitude_,"units", units), string("radians")) )
+ const char *units = 0;
+ if ( magCompare(netcdf.getVariableAttribute(latitude_,"units",units), "radians") )
{
while ( lat!= latitudes.end()) {
*lat=DEG(*lat);
@@ -130,7 +130,7 @@ bool NetcdfGeopointsInterpretor::interpretAsPoints(PointsList& list)
//If the lat-lon units is specified as "radians" convert lat-lon
//to degrees. By default the units are sipposed to be "degrees"
- string units;
+ const char *units = 0;
if ( magCompare(netcdf.getVariableAttribute(latitude_,"units",units), "radians") )
{
while ( lat!= latitudes.end()) {
@@ -457,7 +457,8 @@ void NetcdfXYpointsInterpretor::visit(MetaDataCollector& mdc)
map<string, NetAttribute>::iterator attrIt=attrs.find("_VIEW");
if( attrIt != attrs.end())
{
- const char* val =0; // = attrIt->second.get();
+ const char* val;
+ attrIt->second.get(val);
string str;
if(val) str=string(val);
diff --git a/src/decoders/NetcdfInterpretor.cc b/src/decoders/NetcdfInterpretor.cc
index ae23b45..b47f304 100644
--- a/src/decoders/NetcdfInterpretor.cc
+++ b/src/decoders/NetcdfInterpretor.cc
@@ -22,7 +22,7 @@
#include "NetcdfInterpretor.h"
-#include "NetcdfData.h"
+#include "Netcdf.h"
#include "XmlReader.h"
#include <limits>
@@ -93,16 +93,16 @@ bool NetcdfInterpretor::reference_date(Netcdf& netcdf, const string& var, const
}
double missing_value = netcdf.getMissing(var, missing_attribute_);
- string date = netcdf.getVariableAttribute(var, "reference_date", string(""));
+ string date = netcdf.getVariableAttribute(var, "reference_date", "");
if ( date.empty() ) return false;
originals.reserve(coords.size());
for (vector<double>::iterator c = coords.begin(); c != coords.end(); ++c)
originals.push_back(*c);
- string units = netcdf.getVariableAttribute(var, "units", string(""));
+ string units = netcdf.getVariableAttribute(var, "units", "");
basedate = date;
double diff = ( refdate.empty() ) ? 0 : DateTime(date) - DateTime(refdate) ;
map<string, double>::const_iterator factor = factors.find(units);
- cout << "last point in days!" << coords.back() << endl;
+
if ( factor != factors.end() )
std::transform(coords.begin(), coords.end(), coords.begin(), Multiply(factor->second, missing_value));
std::transform(coords.begin(), coords.end(), coords.begin(), Plus(diff, missing_value));
@@ -119,13 +119,11 @@ bool NetcdfInterpretor::cf_date(Netcdf& netcdf, const string& var, const string&
}
double missing_value = netcdf.getMissing(var, missing_attribute_);
- cout << " direct " << netcdf.getVariableAttribute(var, "long_name", string("")) << endl;
- string date = netcdf.getVariableAttribute(var, "long_name", string(""));
- cout << "var: " << var << " date-->" << date << endl;
+ string date = netcdf.getVariableAttribute(var, "long_name", "");
if ( date.empty() ) return false;
if ( date != "time" && date != "date and time") return false;
- string units = netcdf.getVariableAttribute(var, "units", string(""));
+ string units = netcdf.getVariableAttribute(var, "units", "");
if ( units.empty() ) return false;
originals.reserve(coords.size());
for (vector<double>::iterator c = coords.begin(); c != coords.end(); ++c)
@@ -161,8 +159,8 @@ string NetcdfInterpretor::getAttribute(const string& var, const string& attr, co
{
Netcdf netcdf(path_, dimension_method_);
if ( var.empty() )
- return netcdf.getAttribute(attr, def);
- return netcdf.getVariableAttribute(var, attr, def);
+ return netcdf.getAttribute(attr, def.c_str());
+ return netcdf.getVariableAttribute(var, attr, def.c_str());
}
void NetcdfInterpretor::visit(TextVisitor& title)
@@ -176,7 +174,7 @@ void NetcdfInterpretor::visit(TextVisitor& title)
tag.decode(*t);
}
Netcdf netcdf(path_, dimension_method_);
- title.addAutomaticTitle(netcdf.getAttribute("title", string("NO TITLE")));
+ title.addAutomaticTitle(netcdf.getAttribute("title", "NO TITLE"));
}
void NetcdfInterpretor::getAttributes(Netcdf& nc,const string& varName,string& keys,string& values)
@@ -187,9 +185,9 @@ void NetcdfInterpretor::getAttributes(Netcdf& nc,const string& varName,string& k
bool first=true;
for(map<string, NetAttribute>::iterator it=var.attributes_.begin(); it != var.attributes_.end(); it++)
{
- const char* val = 0; //it->second.get();
+ const char* val;
string str;
-
+ it->second.get(val);
if(val) str=string(val);
if(!first)
diff --git a/src/decoders/NetcdfMatrixInterpretor.cc b/src/decoders/NetcdfMatrixInterpretor.cc
index cb03343..2f32969 100644
--- a/src/decoders/NetcdfMatrixInterpretor.cc
+++ b/src/decoders/NetcdfMatrixInterpretor.cc
@@ -23,7 +23,7 @@
#include "NetcdfMatrixInterpretor.h"
#include "Factory.h"
-#include "NetcdfData.h"
+#include "Netcdf.h"
#include "Coordinate.h"
#include "Layer.h"
#include "TextVisitor.h"
@@ -58,7 +58,7 @@ bool NetcdfMatrixInterpretor::interpretAsMatrix(Matrix** matrix)
double missing = netcdf.getMissing(field_, missing_attribute_);
matrix_->missing(missing);
- string title = netcdf.getAttribute("title", string("NO TITLE"));
+ string title = netcdf.getAttribute("title", "NO TITLE");
x();
@@ -71,26 +71,16 @@ bool NetcdfMatrixInterpretor::interpretAsMatrix(Matrix** matrix)
setDimensions(dimension_, first, last);
vector<double> rows = dateRows_.empty() ? rows_ : dateRows_;
vector<double> columns = dateColumns_.empty() ? columns_ : dateColumns_;
- int index = 0;
+
for ( vector<double>::iterator r = rows.begin(); r != rows.end(); r++) {
vector<string> dims;
ostringstream x,y;
- if ( magCompare(dimension_method_, "index" ) ) {
- y << y_ << "/" << index << "/" << index;
- x << x_ << "/" << 0 << "/" << columns.size()-1;
- }
- else {
- x.precision(20);
- y.precision(20);
-
- y << y_ << "/" << *r << "/" << *r;
- x << x_ << "/" << columns.front() << "/" << columns.back();
- }
- std::copy(dimension_.begin(), dimension_.end(), std::back_inserter(dims));
+ x.precision(20);
+ y.precision(20);
+ y << y_ << "/" << *r;
+ x << x_ << "/" << columns.front() << "/" << columns.back();
dims.push_back(y.str());
dims.push_back(x.str());
- index++;
-
setDimensions(dims, first, last);
vector<double> data;
netcdf.get(field_, data, first, last);
diff --git a/src/decoders/NetcdfOrcaInterpretor.cc b/src/decoders/NetcdfOrcaInterpretor.cc
index e142887..38a4f18 100644
--- a/src/decoders/NetcdfOrcaInterpretor.cc
+++ b/src/decoders/NetcdfOrcaInterpretor.cc
@@ -21,7 +21,7 @@
#include "NetcdfOrcaInterpretor.h"
#include "Factory.h"
-#include "NetcdfData.h"
+#include "Netcdf.h"
#include <limits>
using namespace magics;
@@ -43,7 +43,7 @@ bool NetcdfOrcaInterpretor::interpretAsMatrix(Matrix** data)
Netcdf netcdf(path_, dimension_method_);
NetVariable var = netcdf.getVariable(longitude_);
- vector<size_t> dims;
+ vector<long> dims;
var.getDimensions(dims);
diff --git a/src/decoders/NetcdfVectorInterpretor.cc b/src/decoders/NetcdfVectorInterpretor.cc
index 1399e01..bfa8735 100644
--- a/src/decoders/NetcdfVectorInterpretor.cc
+++ b/src/decoders/NetcdfVectorInterpretor.cc
@@ -23,7 +23,7 @@
#include "NetcdfVectorInterpretor.h"
#include "Factory.h"
-#include "NetcdfData.h"
+#include "Netcdf.h"
#include "Coordinate.h"
#include "Coordinate.h"
@@ -123,7 +123,7 @@ void NetcdfGeoVectorInterpretor::customisedPoints(const Transformation& transfor
//If the lat-lon units is specified as "radians" convert lat-lon
//to degrees. By default the units are sipposed to be "degrees"
- string units;
+ const char *units = 0;
if ( magCompare(netcdf.getVariableAttribute(latitude_,"units",units), "radians") )
{
while ( lat!= latitudes.end()) {
@@ -203,7 +203,7 @@ void NetcdfGeoPolarMatrixInterpretor::customisedPoints(const Transformation&, co
//If the lat-lon units is specified as "radians" convert lat-lon
//to degrees. By default the units are sipposed to be "degrees"
- string units;
+ const char *units = 0;
if ( magCompare(netcdf.getVariableAttribute(latitude_,"units",units), "radians") )
{
while ( lat!= latitudes.end()) {
diff --git a/src/decoders/ShapeDecoder.cc b/src/decoders/ShapeDecoder.cc
index fed983a..1fd83bd 100644
--- a/src/decoders/ShapeDecoder.cc
+++ b/src/decoders/ShapeDecoder.cc
@@ -399,6 +399,8 @@ void ShapeDecoder::decode(vector<Polyline*>& data, const Transformation& transfo
}
if ( index ) {
poly->rotate(index);
+ // Clean the south pole ...
+
}
}
SHPDestroyObject(psShape);
diff --git a/src/drivers/BaseDriver.cc b/src/drivers/BaseDriver.cc
index 1075290..30f7633 100644
--- a/src/drivers/BaseDriver.cc
+++ b/src/drivers/BaseDriver.cc
@@ -554,7 +554,7 @@ void BaseDriver::printLine(const Polyline &line) const
renderWindArrow(arrow);
/*
{
- cout << "STREAMLINES >>>>>>>>>>>>>>>>>>> angle: " << angle<<" x:"<<pro_x<<" y:"<<pro_y<< endl;
+
int ewn=5;
setNewColour(Colour("red"));
setNewLineWidth(4.);
diff --git a/src/drivers/MgQ/MgQLayerItem.cc b/src/drivers/MgQ/MgQLayerItem.cc
index df35c7b..7b9d8f8 100644
--- a/src/drivers/MgQ/MgQLayerItem.cc
+++ b/src/drivers/MgQ/MgQLayerItem.cc
@@ -82,9 +82,6 @@ MgQLayerItem::MgQLayerItem(Layer &layer,MgQLayoutItem *layout,int stepNum) :
{
histoItems_ << 0;
}
-
- // Show layer according to its visibility
- setData(MgQ::ItemIsVisibleKey,layer_.visibility());
}
MgQLayerItem::~MgQLayerItem()
diff --git a/src/drivers/MgQ/MgQPlotScene.cc b/src/drivers/MgQ/MgQPlotScene.cc
index 37a617b..26cb1f2 100644
--- a/src/drivers/MgQ/MgQPlotScene.cc
+++ b/src/drivers/MgQ/MgQPlotScene.cc
@@ -124,7 +124,6 @@ void MgQPlotScene::clearBeforeNewRequest()
void MgQPlotScene::saveStateBeforeNewRequest()
{
-#if 0
foreach(QList<MgQLayerState*> sc,previousSceneState_)
{
foreach(MgQLayerState* st, sc)
@@ -148,12 +147,10 @@ void MgQPlotScene::saveStateBeforeNewRequest()
previousSceneState_ << vec;
}
-#endif
}
//Temporary solution until layers handled properly in Metview 4
void MgQPlotScene::restoreLayerState()
-{
-#if 0
+{
/*qDebug() << "restoreLayerState";
foreach(QList<MgQLayerState*> sc,previousSceneState_)
{
@@ -218,7 +215,6 @@ void MgQPlotScene::restoreLayerState()
}
-#endif
}
void MgQPlotScene::addSceneItem(MgQSceneItem *item)
diff --git a/src/drivers/MgQ/MgQSceneItem.cc b/src/drivers/MgQ/MgQSceneItem.cc
index f82205a..e80f388 100644
--- a/src/drivers/MgQ/MgQSceneItem.cc
+++ b/src/drivers/MgQ/MgQSceneItem.cc
@@ -364,13 +364,10 @@ void MgQSceneItem::updateLayers()
void MgQSceneItem::addLayerItem(MgQLayerItem* item)
{
- layerItems_.push_back(item);
-
-//------------------------------------------------------------
-// FAMI20160913: JUST TO MAKE IT WORK FOR THE MOMENT.
-// Uncomment command below:
-// ASSERT(item->layer().zindex() >= 0);
- item->setStackLevel(item->layer().zindex());
+ layerItems_.push_back(item);
+ //item->setStackLevel(layerItems_.count()-1);
+ ASSERT(item->layer().zindex() >= 0);
+ item->setStackLevel(item->layer().zindex());
}
diff --git a/src/libMagWrapper/MagPlus.cc b/src/libMagWrapper/MagPlus.cc
index 5601e52..ea29eab 100644
--- a/src/libMagWrapper/MagPlus.cc
+++ b/src/libMagWrapper/MagPlus.cc
@@ -231,7 +231,6 @@ MagPlus::MagPlus() : root_(0), superpage_(-1), geographical_(true), mode_(intera
sceneCreators_["MWIND"] = &MagPlus::wind;
sceneCreators_["MGRAPH"] = &MagPlus::graph;
sceneCreators_["SUPERPAGE"] = &MagPlus::superpage;
- sceneCreators_["LAYER"] = &MagPlus::layer;
sceneCreators_["PTEXT"] = &MagPlus::ptext;
sceneCreators_["MTEXT"] = &MagPlus::text;
sceneCreators_["MLEGEND"] = &MagPlus::legend;
@@ -293,21 +292,6 @@ bool MagPlus::newpage(magics::MagRequest& in)
return false;
}
-bool MagPlus::layer(magics::MagRequest& in)
-{
- cout << "MagPlus::layer" << endl;
- in.print();
- int visibility = in("VISIBILITY");
- visibility_ = visibility;
- zindex_ = in("STACKING_ORDER");
- transparency_ = in("TRANSPARENCY");
- id_ = (string) in("_ID");
- layer_ = (string) in("_NAME");
-
-
- return false;
-}
-
bool MagPlus::psdriver(magics::MagRequest& in)
{
@@ -418,7 +402,7 @@ bool MagPlus::page_update(magics::MagRequest& in)
// get the Metview ID;
// reset the page!!!
- int id = in("_ID");
+ int id = in("METVIEW_ID");
FortranViewNodeWrapper* page = pages_[id];
page->set(in);
FortranViewNodeAttributes* node= page->object();
@@ -433,20 +417,17 @@ bool MagPlus::page_update(magics::MagRequest& in)
bool MagPlus::page(magics::MagRequest& in)
{
MagLog::dev()<< "page and subpage--->" << endl;
-
sceneCreators_["MLEGEND"] = &MagPlus::legend;
while ( !empty() ) pop();
geographical_ = true;
-
+ in.print();
FortranSceneNodeWrapper scenehelper;
scenehelper.set(in);
-
setIconInfo(in, *scenehelper.object());
-
root_->insert(scenehelper.object());
push(scenehelper.object());
@@ -465,8 +446,8 @@ bool MagPlus::page(magics::MagRequest& in)
viewhelper->set(in);
FortranViewNode* view = viewhelper->object();
- string id = in("_ID");
- int i = in("_ID");
+ string id = in("METVIEW_ID");
+ int i = in("METVIEW_ID");
pages_[i] = viewhelper;
if ( !id.empty() )
{
@@ -489,7 +470,7 @@ bool MagPlus::page(magics::MagRequest& in)
page_ = new FortranViewNodeWrapper();
in("SUBPAGE_MAP_PROJECTION") = "cartesian";
page_->set(in);
- int id = in("_ID");
+ int id = in("METVIEW_ID");
pages_[id] = page_;
}
@@ -497,53 +478,36 @@ bool MagPlus::page(magics::MagRequest& in)
return false; // do not exit
}
-
-
bool MagPlus::cartesian(magics::MagRequest& in) {
string projection = get(in, "MAP_PROJECTION", "cartesian");
- in("SUBPAGE_MAP_PROJECTION") = projection;
+ in("SUBPAGE_MAP_PROJECTION") = projection;
- if ( !page_ ) page_ = new FortranViewNodeWrapper();
- page_->set(in);
- id_ = (string)in("_ID");
- in("_ID") = id_;
+ if ( !page_ ) page_ = new FortranViewNodeWrapper();
+ page_->set(in);
+ FortranViewNode* view = page_->object();
- string zindex = in("STACKING_ORDER");
- zindex_ = zindex.empty() ? -1 : tonumber(zindex);
-
- string visibility = in("VISIBILITY");
- visibility_ = visibility.empty() ? true : tonumber(visibility);
-
- string transparency = in("TRANSPARENCY");
- transparency_ = transparency.empty() ? 0 : tonumber(transparency);
-
-
- layer_ = (string)in("_NAME");
- FortranViewNode* view = page_->object();
- setIconInfo(in, *view);
-
- if ( !id_.empty() )
- {
-
- view->setInteractiveInfo(id_.c_str(),
- in("ZOOM_NUMBER_OF_LEVELS"), in("ZOOM_CURRENT_LEVEL"));
- }
- top()->insert(view);
- push(view);
+ string id = in("METVIEW_ID");
+ if ( !id.empty() )
+ {
+ string id = in("METVIEW_ID");
+ view->setInteractiveInfo(id.c_str(),
+ in("ZOOM_NUMBER_OF_LEVELS"), in("ZOOM_CURRENT_LEVEL"));
+ }
+ top()->insert(view);
+ push(view);
- in.print();
-
+ in.print();
- map<string, ObjectCreator >::iterator creator = sceneCreators_.find(projection);
- if ( creator != sceneCreators_.end() ) {
+ map<string, ObjectCreator >::iterator creator = sceneCreators_.find(projection);
+ if ( creator != sceneCreators_.end() ) {
- (this->*creator->second)(in) ;
- }
+ (this->*creator->second)(in) ;
+ }
- geographical_ = false;
- return false; // do not exit
+ geographical_ = false;
+ return false; // do not exit
}
bool MagPlus::cartesianGrid(magics::MagRequest& in) {
@@ -963,9 +927,6 @@ void MagPlus::setIconInfo(magics::MagRequest& mv, MetviewIcon& object)
iconclass = get(mv, "_VERB", "");
string iconid = get(mv, "_ID", "");
object.icon(iconname, iconclass, iconid);
- if ( layer_.empty() )
- layer_ = "UNKNOW";
- object.layerInfo(visibility_, zindex_, transparency_, id_, layer_);
}
bool MagPlus::gribloop(magics::MagRequest& in)
@@ -991,7 +952,6 @@ bool MagPlus::gribloop(magics::MagRequest& in)
GribLoopWrapper grib;
grib.set(in);
setIconInfo(in, *grib.object());
-
action->loop(grib.object());
#else
@@ -1682,7 +1642,6 @@ bool MagPlus::text(magics::MagRequest& in)
TextVisitorWrapper helper(node);
helper.set(in);
- setIconInfo(in, *helper.object());
top()->text(node);
@@ -1707,7 +1666,6 @@ bool MagPlus::legend(magics::MagRequest& in)
legend = new FortranAutomaticLegendVisitor();
LegendVisitorWrapper helper(legend);
helper.set(in);
- setIconInfo(in, *helper.object());
top()->legend(legend);
return false; // do not exit
}
diff --git a/src/libMagWrapper/MagPlus.h b/src/libMagWrapper/MagPlus.h
index 7d138d9..cfeae9b 100644
--- a/src/libMagWrapper/MagPlus.h
+++ b/src/libMagWrapper/MagPlus.h
@@ -100,7 +100,6 @@ protected:
bool dataloop(magics::MagRequest&);
bool bufr(magics::MagRequest&);
bool visdef(magics::MagRequest&);
- bool layer(magics::MagRequest&);
#ifdef HAVE_ODB
bool geoodb(magics::MagRequest&);
@@ -151,13 +150,6 @@ protected:
MetviewMode mvMode_;
FortranViewNodeWrapper* page_;
vector<Visdef*>* currentMulti_;
-
- // Information related to the current layer
- bool visibility_;
- int zindex_;
- int transparency_;
- string id_;
- string layer_;
#ifdef MAGICS_QT
//! Keep the instance of the QtDrver!
diff --git a/src/params/Axis.xml b/src/params/Axis.xml
index 5d1eb58..1909f8a 100644
--- a/src/params/Axis.xml
+++ b/src/params/Axis.xml
@@ -141,7 +141,7 @@ does it submit to any jurisdiction.
<parameter member="tick" to="bool" default="on" from="string" name="axis_tick">
<documentation> Plot ticks </documentation>
<set name="axis_tick_interval" value="on"> </set>
- <set name="axis_tick_position_list" value="on"> </set>
+ <set name="axis_tick_position" value="on"> </set>
<set name="axis_tick_colour" value="on"> </set>
<set name="axis_tick_size" value="on"> </set>
<set name="axis_tick_thickness" value="on"> </set>
diff --git a/src/params/Boundaries.xml b/src/params/Boundaries.xml
index c668fe9..21e5f79 100644
--- a/src/params/Boundaries.xml
+++ b/src/params/Boundaries.xml
@@ -59,7 +59,7 @@ does it submit to any jurisdiction.
<set name="map_administrative_boundaries_thickness" value="on"> </set>
</parameter>
- <parameter from="stringarray" name="map_administrative_boundaries_countries_list" default="stringarray()" member="administrative_list" to="stringarray" values="Afghanistan:AFG/Algeria:DZA/Angola:AGO/Argentina:ARG/Australia:AUS/Australia CCK:CCK/Australia CXR:CXR/Australia HMD:HMD/Australia NFK:NFK/Austria:AUT/Baikonur Cosmodrome:RUS/Bangladesh:BGD/Belarus:BLR/Bolivia:BOL/Botswana:BWA/Brazil:BRA/Cameroon:CMR/Canada:CAN/Central African Republic:CAF/Chad:TCD/Chile:CHL/China:CHN/Colombia:CO [...]
+ <parameter from="stringarray" name="map_administrative_boundaries_countries_list" default="stringarray()" member="administrative_list" to="stringarray" values="AGO:Angola/DZA:Algeria/EGY:Egypt/BGD:Bangladesh/NAM:Namibia/BOL:Bolivia/GHA:Ghana/CCK:Australia CCK/PAK:Pakistan/LBY:Libya/MYS:Malaysia/PRK:Korea, North/TZA:Tanzania/BWA:Botswana/PRY:Paraguay/SAU:Saudi Arabia/MRT:Mauritania/CHL:Chile/CHN:China/LAO:Laos/GIB:United Kingdom GIB/GIN:Guinea/FIN:Finland/URY:Uruguay/NPL:Nepal/CXR:Austra [...]
<documentation>List of countries for which to show second level administrative borders. The convention used is the 3 Letters ISO Codes 3166 for countries </documentation>
</parameter>
diff --git a/src/visualisers/AutomaticContourMethod.h b/src/visualisers/AutomaticContourMethod.h
index 62a00a0..b3c937a 100644
--- a/src/visualisers/AutomaticContourMethod.h
+++ b/src/visualisers/AutomaticContourMethod.h
@@ -64,14 +64,17 @@ public:
MatrixHandler data(matrix);
MatrixHandler* pMatrixHandler;
if ( matrix.akimaEnable() == false ) {
-
- ContourMethod * pContourMethod =new ContourMethod();
+ if ( matrix.delegate() ) {
+ return new DelegateMatrixHandler(matrix);
+ }
+ ContourMethod * pContourMethod =new ContourMethod();
pMatrixHandler = pContourMethod->handler(matrix, owner);
MagLog::debug() << "Linear contouring, " << "\n";
- //return pMatrixHandler;
- return new DelegateMatrixHandler(matrix);
+ return pMatrixHandler;
+
+
}
double fGeoAreaWidth;
diff --git a/src/visualisers/Axis.cc b/src/visualisers/Axis.cc
index 91fd827..9cd3629 100644
--- a/src/visualisers/Axis.cc
+++ b/src/visualisers/Axis.cc
@@ -91,10 +91,8 @@ void Axis::visit(SceneLayer& layer, vector<LayoutVisitor*>& visitors)
// First we create the layer!
// and push It to the parent layer!
StaticLayer* axis = new NoDataLayer(this);
-
-
- axis->icon(*this);
-
+ axis->id(iconName_);
+ axis->name(iconName_);
layer.add(axis);
for (vector<LayoutVisitor*>::iterator visitor = visitors.begin(); visitor != visitors.end(); ++visitor) {
diff --git a/src/visualisers/CalcStreamlines.cc b/src/visualisers/CalcStreamlines.cc
index 2a980d4..f3f9254 100644
--- a/src/visualisers/CalcStreamlines.cc
+++ b/src/visualisers/CalcStreamlines.cc
@@ -823,18 +823,15 @@ int CalcStreamlines(int density, const float *dir, const GSStruct *gs, OneLineCl
line->Y[0] = y[line_start];
for(int k=1, ll=1, l=line_start+1; ll<len; ll++, l++)
{
- /*if( x[l] != x[l-1] || y[l] != y[l-1] )*/
+
{
line->X[k] = x[l];
line->Y[k] = y[l];
- // std:: << k << " = " << "[" << line->X[k] << ", " << line->Y[k] << "]" << std::endl;
k++;
}
}
- // std::cout << "-----------------------------------------------------------" << std::endl;
-
- linenum++;
+ linenum++;
OneLineClass** new_str_lines = new OneLineClass*[linenum];
for(int ii=0; ii<linenum-1; ii++)
new_str_lines[ii] = str_lines[ii];
diff --git a/src/visualisers/Coastlines.cc b/src/visualisers/Coastlines.cc
index c3385f7..2806189 100644
--- a/src/visualisers/Coastlines.cc
+++ b/src/visualisers/Coastlines.cc
@@ -116,9 +116,8 @@ void Coastlines::visit(SceneLayer& layer, vector<LayoutVisitor*>& visitors)
// First we create the layer!
// and push It to the parent layer!
layer_ = new NoDataLayer(this);
-
- layer_->icon(*this);
-
+ layer_->id(iconName_);
+ layer_->name(iconName_);
layer.add(layer_);
}
for (vector<LayoutVisitor*>::iterator visitor = visitors.begin(); visitor != visitors.end(); ++visitor) {
diff --git a/src/visualisers/EpsGraph.cc b/src/visualisers/EpsGraph.cc
index 7a22f96..68f1564 100644
--- a/src/visualisers/EpsGraph.cc
+++ b/src/visualisers/EpsGraph.cc
@@ -751,7 +751,6 @@ void EpsGraph::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {
resolution_ = (**point)["resolution"];
double missing = (**point)["missing"];
- cout << missing << endl;
double x = (**point)["step"] + box_shift_ *3600;
double width = (box_width_ == -1) ? (**point)["width"] : box_width_ * 3600;
@@ -1043,12 +1042,12 @@ void EpsLight::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
std::sort(eps.begin(), eps.end());
- for (vector<double>::iterator e = eps.begin(); e != eps.end(); ++e) {
+ for (vector<double>::iterator e = eps.begin(); e != eps.begin(); ++e) {
if ( same(*e, 0) )
*e = 0;
- cout << *e << " ";
+ MagLog::debug() << *e << " ";
}
- cout << endl;
+ MagLog::debug() << endl;
double epsmin, eps10, eps25, eps50, eps75, eps90, epsmax;
if ( ninty != (*point)->end() ) {
@@ -1082,7 +1081,7 @@ void EpsLight::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
float height = 1./(colours.size()*4);
for ( vector<Colour>::iterator colour = colours.begin(); colour != colours.end(); ++colour) {
- cout << x << " " << x + width << endl;
+
for (int i = 0; i < 4; i++ ) {
Polyline* box = new Polyline();
box->setColour(*colour);
diff --git a/src/visualisers/IsoPlot.cc b/src/visualisers/IsoPlot.cc
index eab8d20..7730630 100644
--- a/src/visualisers/IsoPlot.cc
+++ b/src/visualisers/IsoPlot.cc
@@ -1278,9 +1278,8 @@ void IsoPlot::isoline(MatrixHandler& data, BasicGraphicsObjectContainer& parent)
}
view.split();
-
- cout << "Nb Thread --> " << view.size() << endl;
-
+
+ // let's start 4 producers...
int c = 0;
VectorOfPointers<vector<IsoProducerData*> > datas;
for ( int i = 0; i < view.size(); i++)
diff --git a/src/visualisers/SymbolAdvancedTableMode.cc b/src/visualisers/SymbolAdvancedTableMode.cc
index fad43bf..1b55afa 100644
--- a/src/visualisers/SymbolAdvancedTableMode.cc
+++ b/src/visualisers/SymbolAdvancedTableMode.cc
@@ -84,9 +84,7 @@ void SymbolAdvancedTableMode::prepare()
}
-
-
-void SymbolAdvancedTableMode::adjust(double min, double max, bool scale, const Transformation& transformation, double scaling)
+void SymbolAdvancedTableMode::adjust(double min, double max)
{
static map<string, TextSymbol::TextPosition> texthandlers;
if ( texthandlers.empty() ) {
@@ -148,14 +146,12 @@ void SymbolAdvancedTableMode::adjust(double min, double max, bool scale, const
if (level+1 == levels_->end() ) break;
MagLog::debug() << "[" << *level << ", " << *(level+1) << "]=" << *marker << "(marker)" << *text << "(text)"<< endl;
- double height = height_method_->height(*level);
- if ( scale )
- height = transformation.ratio() * height * scaling;
+
SymbolProperties properties;
- if ( index )
- properties = SymbolProperties(colourMethod_->right(*level), height, *marker, *text);
+ if ( index )
+ properties = SymbolProperties(colourMethod_->right(*level), height_method_->height(*level), *marker , *text);
else
- properties = SymbolProperties(colourMethod_->right(*level), height,*marker_name, *text);
+ properties = SymbolProperties(colourMethod_->right(*level), height_method_->height(*level), *marker_name, *text);
properties.position_ = position;
properties.font_ = font;
diff --git a/src/visualisers/SymbolAdvancedTableMode.h b/src/visualisers/SymbolAdvancedTableMode.h
index 675f363..fb884cf 100644
--- a/src/visualisers/SymbolAdvancedTableMode.h
+++ b/src/visualisers/SymbolAdvancedTableMode.h
@@ -68,17 +68,25 @@ public:
return SymbolAdvancedTableModeAttributes::accept(node);
}
- virtual SymbolMode* clone() const {
- SymbolAdvancedTableMode* object = new SymbolAdvancedTableMode();
- object->copy(*this);
- return object;
- }
- void adjust(double, double, bool, const Transformation&, double);
+ virtual SymbolMode* clone() const {
+ SymbolAdvancedTableMode* object = new SymbolAdvancedTableMode();
+ object->copy(*this);
+ return object;
+ }
+ virtual void adjust(double , double );
+
void copy(const SymbolAdvancedTableMode& other) {
SymbolAdvancedTableModeAttributes::copy(other);
SymbolModeAttributes::copy(other);
}
+
+
+
+
+
+
+
int getCount() const { return count_; }
int getTolerance() const { return tolerance_; }
double getReference() const { return reference_; }
diff --git a/src/visualisers/SymbolMode.cc b/src/visualisers/SymbolMode.cc
index 894d47c..518da12 100644
--- a/src/visualisers/SymbolMode.cc
+++ b/src/visualisers/SymbolMode.cc
@@ -270,12 +270,7 @@ void SymbolIndividualMode::visit(LegendVisitor& legend)
symbol->setHeight(legend_height_);
legend.add(new SimpleSymbolEntry(legend_text_, symbol));
}
-void SymbolIndividualMode::adjust(double, double, bool, const Transformation&, double) {
-}
-void SymbolTableMode::adjust(double, double, bool, const Transformation&, double) {
-
-}
void SymbolIndividualMode::visit(Data& data, LegendVisitor& legend)
{
diff --git a/src/visualisers/SymbolMode.h b/src/visualisers/SymbolMode.h
index 2d11a75..4487df7 100644
--- a/src/visualisers/SymbolMode.h
+++ b/src/visualisers/SymbolMode.h
@@ -73,8 +73,8 @@ public:
virtual void visit(Data&, LegendVisitor& legend) { visit(legend); }
virtual void visit(Data&, HistoVisitor&);
-
- virtual void adjust(double, double, bool, const Transformation&, double) {}
+ //virtual void adjust(double min, double max) {}
+ virtual void adjust(double , double ) {}
void set(const string& type) { type_ = type; }
protected:
@@ -124,7 +124,7 @@ public:
return object;
}
- void adjust(double, double, bool, const Transformation&, double);
+
virtual void visit(LegendVisitor&);
void prepare() { update(); properties();}
void update();
@@ -194,8 +194,6 @@ public:
return SymbolTableModeAttributes::accept(node);
}
-
- void adjust(double, double, bool, const Transformation&, double);
void visit(LegendVisitor&);
void visit(Data&, LegendVisitor&);
diff --git a/src/visualisers/SymbolPlotting.cc b/src/visualisers/SymbolPlotting.cc
index 3132d69..75a8bb9 100644
--- a/src/visualisers/SymbolPlotting.cc
+++ b/src/visualisers/SymbolPlotting.cc
@@ -46,15 +46,16 @@ void SymbolPlotting::print(ostream& out) const
out << "]";
}
-double SymbolPlotting::height(const Transformation& transformation, double height)
+double SymbolPlotting::height(const Transformation&, double height)
{
if ( scaling_method_ == false )
return height;
// get Area !
- return transformation.ratio() * scaling_level_0_ * scaling_factor_;
-
+ //return transformation.ratio() * scaling_level_0_ * scaling_factor_;
+ return scaling_level_0_ * scaling_factor_;
+
}
@@ -169,7 +170,7 @@ void SymbolPlotting::operator()(Data& data, BasicGraphicsObjectContainer& out)
// Some Mode need to know the min and max of the data, in order to adjust the
// computation of the levels
- (*mode_).adjust(points.min(), points.max(), scaling_method_, transformation, scaling_factor_);
+ (*mode_).adjust(points.min(), points.max());
if ( legend_only_ )
return;
diff --git a/test/bufr.py b/test/bufr.py
index 95abcb8..65f94e4 100644
--- a/test/bufr.py
+++ b/test/bufr.py
@@ -54,7 +54,7 @@ title = \
# To the plot
-print("plot")
+print "plot"
plot( output, europe, obs, coast, )
tofortran(ref, output, europe, obs, coast, )
diff --git a/test/cairo.py b/test/cairo.py
index 356d637..95fab25 100644
--- a/test/cairo.py
+++ b/test/cairo.py
@@ -62,7 +62,7 @@ legend = mlegend(
# To the plot
-print("plot")
+print "plot"
plot( output, europe, coast, )
tofortran(ref, output, europe, coast, )
diff --git a/test/grib.py b/test/grib.py
index 3032524..c647607 100644
--- a/test/grib.py
+++ b/test/grib.py
@@ -73,7 +73,7 @@ legend = mlegend(
# To the plot
-print("plot")
+print "plot"
plot( output, europe, data, cont, coast, title)
diff --git a/tools/xml2mv.py b/tools/xml2mv.py
index 50c8175..b360028 100755
--- a/tools/xml2mv.py
+++ b/tools/xml2mv.py
@@ -1,9 +1,9 @@
-#!/usr/bin/env python
+#!/usr/bin/env python
# (C) Copyright 1996-2016 ECMWF.
-#
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -15,8 +15,8 @@ import sys
if(len(sys.argv) != 6) :
- print("\n\tYou need to give 4 input parameters:")
- print("\n\t %s source.xml targetDef CLASS_NAME rulesDef\n",sys.argv[0])
+ print ("\n\tYou need to give 4 input parameters:")
+ print ("\n\t %s source.xml targetDef CLASS_NAME rulesDef\n") % sys.argv[0]
sys.exit()
@@ -81,7 +81,7 @@ class ObjectHandler(ContentHandler):
def default(self, attrs):
val = attrs.get("metview_default");
- if val is None:
+ if ( isinstance(val, NoneType) ):
val = attrs.get("default");
if (val == "") :
@@ -126,7 +126,7 @@ class ObjectHandler(ContentHandler):
def characters(self, data):
pass
-
+
# addhidden - if the appropriate flag is set in the attributes, return the text that will
# make the parameter hidden (but available) in Metview
@@ -382,7 +382,7 @@ class ObjectHandler(ContentHandler):
# we now know that the clause should go into position 'position' in the new tuple
if self.debug:
- print("put into position " + str(position))
+ print ("put into position " + str(position ))
if position == 0:
firstpart = ()
secondpart = (newtuple3,)
@@ -540,7 +540,7 @@ class ObjectHandler(ContentHandler):
try:
file = open(fname, "r")
if (self.debug):
- print("Opened (start class)" + fname)
+ print ("Opened (start class)" + fname)
self.filehistory.append(fname)
object = ObjectHandler()
object.myoptions = []
@@ -585,7 +585,7 @@ class ObjectHandler(ContentHandler):
metview_type = attrs.get("metview_interface")
if metview_type != None:
type = metview_type
- if (type in self.types):
+ if (self.types.has_key(type)):
f = self.types[type]
self.newparam(self.param, f(self, attrs), self.default(attrs))
else:
@@ -613,7 +613,7 @@ class ObjectHandler(ContentHandler):
# self.classes[attrs.get("name")]["inherits_reqs_from"].add(self.classname)
# print "YClass " + attrs.get("name") + " inherits_reqs_from " + self.classname
if attrs.get("docdive") != 'no' and attrs.get("doc_inherits") != 'no' :
- if attrs.get("xmlfile") is not None:
+ if ( not(isinstance(attrs.get("xmlfile"), NoneType))):
fname = "/%s.xml" % attrs.get("xmlfile")
else:
fname = "%s/%s.xml" % (sys.argv[1], attrs.get("name"))
@@ -622,7 +622,7 @@ class ObjectHandler(ContentHandler):
file = open(fname, "r")
self.filehistory.append(fname)
if (self.debug):
- print("Opened (start option) " + fname)
+ print ("Opened (start option) " + fname)
object = ObjectHandler()
object.myoptions = []
object.myrules = {}
@@ -675,13 +675,13 @@ class ObjectHandler(ContentHandler):
self.last = self.last + "\t} = %s\n" % self.defparam
self.newparam(self.param, self.last, self.defparam)
if (self.debug) :
- print(" endparam: " + self.param)
- print(" endparam SL: \n" + self.last)
+ print (" endparam: " + self.param)
+ print (" endparam SL: \n" + self.last)
self.last = ""
for option in self.myoptions:
for p in option:
#print " adding newparam from option: " + p[0]
- self.newparam(p[0], p[1], p[2])
+ self.newparam(p[0], p[1], p[2])
self.myoptions = []
for rules in self.myrules:
current = rules
@@ -694,7 +694,7 @@ class ObjectHandler(ContentHandler):
except:
pass
unsets.append(p[0])
-
+
for unset in self.myrules:
if (unset == rules):
for p in self.myrules[unset]:
@@ -710,8 +710,8 @@ class ObjectHandler(ContentHandler):
pass
self.myrules = {}
-
-
+
+
if (name == "magics") :
if self.toplevel:
#print "SL (end class): " + self.last
@@ -838,7 +838,7 @@ class ObjectHandler(ContentHandler):
prevparam = condition[0]
#print('condition rules:')
#print condition
- rules.write(" " + condition[0].upper() + " != " + condition[1].upper())
+ rules.write(" " + condition[0].upper() + " <> " + condition[1].upper())
rules.write(" %then")
# for optparam in self.optionalparams2[conditions]:
for optparam in clause[1]:
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/magics.git
More information about the debian-science-commits
mailing list